Hello everyone,
I'm working on an iOS application using Objective-C and UITabBarController. My app has more than 5 tabs, so the additional tabs are placed under the "More" tab. However, I've encountered an issue specific to iOS 18 where the first item in the "More" tab does not show up properly. This issue does not occur in iOS 17 or earlier versions.
Here's my setup method:
(void)mainTabbarSetUp {
NSMutableArray *tabItemArray = [NSMutableArray array];
UIViewController *viewController1, *viewController2, *viewController3, *viewController4, *viewController5, *viewController6, *viewController7;
UINavigationController *navviewController1, *navviewController2, *navviewController3, *navviewController4, *navviewController5, *navviewController6, *navviewController7;
viewController1 = [[UIViewController alloc] init];
navviewController1 = [[UINavigationController alloc] initWithRootViewController:viewController1];
navviewController1.tabBarItem.title = @"Watch List";
navviewController1.tabBarItem.image = [UIImage imageNamed:@"tab_icn_watchlist"];
[tabItemArray addObject:navviewController1];
// Similarly adding other view controllers...
viewController6 = [[UIViewController alloc] init];
navviewController6 = [[UINavigationController alloc] initWithRootViewController:viewController6];
navviewController6.tabBarItem.title = @"Cancelled";
navviewController6.tabBarItem.image = [UIImage imageNamed:@"tab_icn_cancelled"];
[tabItemArray addObject:navviewController6];
self.mainTabBarController.viewControllers = tabItemArray;
}
What I've Tried:
Verified that each view controller is correctly initialized and assigned to a UINavigationController before being added to the tab array.
Logged the contents of the moreNavigationController to confirm that it contains the correct view controllers.
Tested by reducing the number of view controllers to less than 5, and the issue does not occur.
Ensured that all UINavigationControllers are configured consistently (e.g., translucency, bar style, etc.).
UIKit
RSS for tagConstruct and manage graphical, event-driven user interfaces for iOS or tvOS apps using UIKit.
Post
Replies
Boosts
Views
Activity
I have an iOS app that relies on dynamic text size such that all fonts in the app respect the user's setting of Text Size in the iOS Settings app.
This app also runs on macOS via Mac Catalyst. But until macOS 14 Sonoma, there was no Text Size setting in the macOS Settings app. But even as of Sonoma, the Text Size setting isn't usable by 3rd party apps. And Sequoia doesn't seem to change that.
As a work around, my Mac Catalyst app provides its own Text Size setting. I was able to make it work by providing my own UIApplication subclass and overriding preferredContentSizeCategory. Under macOS 12 to macOS 14, this workaround works just fine and all fonts in the app created with code such as UIFont.preferredFont(forTextStyle:) gives appropriately sized fonts based on the overridden content size category.
However, this workaround stopped working with macOS 15 Sequoia. I've also tried code such as:
self.window.traitOverrides.preferredContentSizeCategory = myCustomSizeCategoryValue
and
self.window.maximumContentSizeCategory = myCustomSizeCategoryValue
self.window.minimumContentSizeCategory = myCustomSizeCategoryValue
in the scene delegate but that made no difference.
Is there any way to get code such as UIFont.preferredFont(forTextStyle:) to return an appropriately sized font based on some app provided content size category in a Mac Catalyst app running under macOS 15?
It sure would be nice if Mac Catalyst apps automatically responded to the macOS Text Size setting under Settings -> Accessibility -> Display -> Text Size just like a native iOS app.
Hello
I'm working on implementing some changes to my app's tab bar, particularly to support some features in the new iPad floating tab bar, which has required me to adopt some of the new tab APIs from iOS 18.
The issue I've encountered is that I would like the tabs visible in regular (floating tab bar) and compact (bottom tab bar) to be slightly different. The compact variant should show a subset of the tabs visible on iPad. For example:
Floating tab bar: Use tabs A, B, C
Bottom tab bar: Use tabs A, B
I'm finding this quite difficult, especially in the scenario of split view on iPad, where the size class and tab bar location can change as the user interacts with the app.
I went down the route of changing my tab bar controller's tabs property when the trait collection changed
tabBarController.tabs = eligibleTabs
where eligibleTabs for compact passes tabs AB, and when in regular - ABC. This throws an exception
UIViewController cannot be shared between multiple UITab
*** Assertion failure in -[UITab viewController], UITab.m:173
I'm not sharing view controllers between tabs. I can only assume that the system doesn't like me passing the same values (always at least tabs A & B) multiple times to the tabs property.
I then later noticed a new iOS 18 property on UITabBarController - compactTabIdentifiers. This seemed like exactly what I was looking for: An optional filter to display only select root-level tabs when in a compact appearance. Default is nil, which would make all tabs available.
So I changed my implementation:
tabBarController.tabs = [tabA, tabB, tabC] tabBarController.compactTabIdentifiers = [tabAIdentifier, tabBIdentifier]
and don't make any explicit updates when split view is enabled.
Unfortunately this doesn't seem to work, at least not how I would expect it to. When enabling split view on iPad, the bottom tab bar appears, but it doesn't respect the tab identifiers I passed in tabBarController.compactTabIdentifiers.
I'm not sure if this a bug or that I'm not really understanding how to use tabBarController.compactTabIdentifiers.
Does anyone have any insight on this?
I encountered a crash when calling the tabBarView:didSelectIndex: method, and it only happens on iOS 18.
Here is crash report:
`OS Version: iPhone OS 18.0.1 (22A3370)
Report Version: 105
SDK Version: 0.0.4
Exception Type: SIGABRT
Exception Codes: #0 at 0x1f0acb274
Crashed Thread: 0
Application Specific Information:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Layout requested for visible navigation bar, <UINavigationBar: 0x11266ef80; frame = (0 -91; 428 44); autoresize = W; tintColor = UIExtendedSRGBColorSpace 1 1 1 0.8; layer = <CALayer: 0x301e14800>> delegate=0x112670600 standardAppearance=0x3035b3720 scrollEdgeAppearance=0x3035b3b10, when the top item belongs to a different navigation bar. topItem = <UINavigationItem: 0x14309cf00> title='' titleView=0x15b1af700 style=navigator leftBarButtonItems=0x301c08940 rightBarButtonItems=0x301caa180, navigation bar = <UINavigationBar: 0x11266e080; frame = (0 -91; 428 44); autoresize = W; tintColor = UIExtendedSRGBColorSpace 1 1 1 0.8; layer = <CALayer: 0x301e1d0a0>> delegate=0x112670000 standardAppearance=0x30355ae60 scrollEdgeAppearance=0x30355aed0, possibly from a client attempt to nest wrapped navigation controllers.'
Last Exception Backtrace:
0 CoreFoundation 0x00000001a0cad08c 0x1a0c29000 + 540812
1 libobjc.A.dylib 0x000000019dfaf2e4 0x19df98000 + 94948
2 Foundation 0x00000001a007e15c 0x19f85c000 + 8528220
3 UIKitCore 0x00000001a36b6028 0x1a33f4000 + 2891816
4 UIKitCore 0x00000001a3404248 0x1a33f4000 + 66120
5 UIKitCore 0x00000001a354d878 0x1a33f4000 + 1415288
6 QuartzCore 0x00000001a2749630 0x1a26d1000 + 493104
7 UIKitCore 0x00000001a3447cd0 0x1a33f4000 + 343248
8 UIKitCore 0x00000001a34e9a60 0x1a33f4000 + 1006176
9 UIKitCore 0x00000001a354aa48 0x1a33f4000 + 1403464
10 UIKitCore 0x00000001a34f1c64 0x1a33f4000 + 1039460
11 UIKitCore 0x00000001a368e2c8 0x1a33f4000 + 2728648
12 UIKitCore 0x00000001a368c504 0x1a33f4000 + 2721028
13 UIKitCore 0x00000001a34193c8 0x1a33f4000 + 152520
14 UIKitCore 0x00000001a34191f4 0x1a33f4000 + 152052
15 UIKitCore 0x00000001a340ae84 0x1a33f4000 + 93828
16 CoreAutoLayout 0x00000001c3ad7030 0x1c3ac5000 + 73776
17 UIKitCore 0x00000001a340ddc8 0x1a33f4000 + 105928
18 UIKitCore 0x00000001a340c7f0 0x1a33f4000 + 100336
19 UIKitCore 0x00000001a378087c 0x1a33f4000 + 3721340
20 UIKitCore 0x00000001a37804f0 0x1a33f4000 + 3720432
21 UIKitCore 0x00000001a377e814 0x1a33f4000 + 3713044
22 UIKitCore 0x00000001a37ee8a4 0x1a33f4000 + 4171940
23 UIKitCore 0x00000001a37edf14 0x1a33f4000 + 4169492`
I'm trying to create a brush by drawing in CGContext using a UIImage for a brush. However, I when I try drawing, the stroke is antialiased when I don't want it to be. I tried
context.interpolationQuality = .none
context.setShouldAntialias(false)
but it doesn't seem to work. Is it a problem with my brush or resizing the brush maybe?? (Also this problem doesn't occur when I draw a regular stroke without the brush.)
Any help or advice would be greatly appreciated!
Here is my draw function
override func draw(_ rect: CGRect) {
super.draw(rect)
guard let context = UIGraphicsGetCurrentContext() else { return }
context.interpolationQuality = .none
context.setShouldAntialias(false)
for stroke in strokes {
let brush = UIColor.blue.circle(size: CGSize(width: CGFloat(stroke.width * 10), height: CGFloat(stroke.width * 10))).mask(color: UIColor(cgColor: stroke.color))
var first = true
for point in stroke.points {
if first {
first = false
context.move(to: point)
continue
}
context.addLine(to: point, using: brush)
}
}
}
Circle brush
extension UIColor {
func circle(size: CGSize = CGSize(width: 1, height: 1)) -> UIImage {
return UIGraphicsImageRenderer(size: size).image { rendererContext in
self.setFill()
UIBezierPath(ovalIn: CGRect(origin: .zero, size: size)).fill()
}
}
}
CGConext extension where I overloaded addLine
extension CGContext {
func addLine(to point: CGPoint, using brush: UIImage, density: CGFloat = 1.0) {
var frame: CGRect = .zero
frame.size = brush.size
let lastPoint = self.currentPointOfPath
let distanceX = point.x - lastPoint.x
let distanceY = point.y - lastPoint.y
let distanceR = sqrt(pow(distanceX, 2) + pow(distanceY, 2))
let deltaR = (1.0 / density)
let numOfSteps = ceil(distanceR / deltaR)
var renders : CGFloat = 0.0
let deltaX = distanceX / numOfSteps
let deltaY = distanceY / numOfSteps
var currentCenter = lastPoint
repeat {
frame.origin.x = currentCenter.x - frame.width / 2.0
frame.origin.y = currentCenter.y - frame.height / 2.0
brush.draw(in: frame)
currentCenter.x += deltaX
currentCenter.y += deltaY
renders += 1.0
} while (renders <= numOfSteps)
self.move(to: point)
}
}
Hi everyone,
If you're encountering the following error in Xcode while executing a simple webbrowser.open() command in your Python file, you're in the right place:
"BUG IN CLIENT OF UIKIT: The caller of UIApplication.openURL(:) needs to migrate to the non-deprecated UIApplication.open(:options:completionHandler:). Force returning false (NO)."
This issue arises because, starting from iOS 18, the UIApplication.openURL(:) method has been deprecated. If you created your project, dependencies, and the kivy-ios folder before iOS 18, every time you try to open a URL, the deprecated method will be called.
To resolve this issue without rebuilding the entire project and waiting for the kivy-ios toolchain to be updated, simply follow these steps:
At the very top of your main.py file remplace import webbrowser by :
from pyobjus import autoclass
from pyobjus.dylib_manager import load_framework
load_framework('/System/Library/Frameworks/UIKit.framework')
NSURL = autoclass('NSURL')
UIApplication = autoclass('UIApplication')
def open_url(url):
nsurl = NSURL.URLWithString_(url)
app = UIApplication.sharedApplication()
options = {}
app.openURL_options_completionHandler_(nsurl, options, None)
Then replace all your webbrowser.open(url) commands by open_url(url)
You no longer need webbrowser.
Hope it helped.
Summary
In iOS 18, the UICollectionViewDelegate method
collectionView(_:targetIndexPathForMoveOfItemFromOriginalIndexPath:atCurrentIndexPath:toProposedIndexPath:)
is not being called when moving items in a UICollectionView. This method works as expected in iOS 17.5 and earlier versions.
Steps to Reproduce
Create a UICollectionView with drag and drop enabled.
Implement the UICollectionViewDelegate method:
func collectionView(_ collectionView: UICollectionView, targetIndexPathForMoveOfItemFromOriginalIndexPath originalIndexPath: IndexPath, atCurrentIndexPath currentIndexPath: IndexPath, toProposedIndexPath proposedIndexPath: IndexPath) -> IndexPath {
print("🐸 Move")
return proposedIndexPath
}
Run the app on iOS 18.
Attempt to drag and drop items within the collection view.
Expected Behavior
The method should be called during the drag and drop operation, and "🐸 Move" should be printed to the console.
Actual Behavior
The method is not called, and nothing is printed to the console. The drag and drop operation still occurs, but without invoking this delegate method.
Configuration
iOS Version: 18
Xcode Version: Xcode 16.0.0
The UITextView.allowedWritingToolsResultOptions has no effect to how "Writing Tools" feature works. When it is set to empty, it still offer all options in the Writing Tools popup dialog. The result is that it is not possible to limit output results to eg. only plain text, or disable tables in output.
let textView = UITextView()
textView.isEditable = true
textView.writingToolsBehavior = .complete
textView.allowedWritingToolsResultOptions = []
resulting Writing Tools has all options available. I Tested with TextKit1 and TextKit 2 setup.
tested on iPadOS 18.1 beta (22B5069a)
Report: FB15429824
Use a UITabBarController to load two ViewControllers, A and B, both wrapped in UINavigationController.
In A’s viewDidLoad method, push to C, with C’s hidesBottomBarWhenPushed set to true. When popping back to A, the tab bar flickers and then disappears.
In versions lower than iOS 18, after popping back, the tabBar does not flicker and disappear.
A ViewController
override func viewDidLoad() {
super.viewDidLoad()
let vc = CViewController()
vc.hidesBottomBarWhenPushed = true
navigationController?.pushViewController(vc, animated: true)
// Do any additional setup after loading the view.
}
MACCATALYST
I am able to hide title bar title using below line.
windowScene.titlebar?.titleVisibility = .hidden
but,
windowScene.titlebar?.toolbarStyle = .unifiedCompact
windowScene.titlebar?.toolbar = nil
with above 2 lines, my title bar is still visible with system defined some background color.
I want to make it transparent(clear background color)
Below style case was crash after 17.6.1
import UIKit
import PlaygroundSupport
class MyViewController : UIViewController {
override func loadView() {
let view = UIView()
view.backgroundColor = .white
let titleText = UITextView(frame: CGRect(origin: .zero, size: CGSize(width: 82, height: 100)))
titleText.textContainer.maximumNumberOfLines = 2
titleText.textContainer.lineFragmentPadding = 0
titleText.textContainer.lineBreakMode = .byTruncatingTail
titleText.textContainerInset = UIEdgeInsets.zero
let attributedText = NSMutableAttributedString(string: text, attributes: [.font: UIFont.systemFont(ofSize: 14), .foregroundColor: UIColor.red])
titleText.attributedText = attributedText
view.addSubview(titleText)
self.view = view
}
}
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()
Hi.
Since Xcode 16 and/or iOS 18.0 (I upgraded at the same time), I have an strange effect in the lower (let's say) 20% section of the Navigation Bar when changing to another tab, and this independently if large titles are used or not. Mentioned section is brighter or darker than the rest of the Navigation Bar background, depending on which background tint is used. This effect lasts about 0.3 seconds, but is clearly visible, quite disturbing and new as of Xcode 16 and/or iOS 18.0.
I use the code below in AppDelegate to get a gradient coloured Navigation Bar background.
let appearance = UINavigationBarAppearance()
UINavigationBar.appearance().standardAppearance = appearance
UINavigationBar.appearance().compactAppearance = appearance
UINavigationBar.appearance().scrollEdgeAppearance = appearance
UINavigationBar.appearance().compactScrollEdgeAppearance = appearance
If I don't use above code., the background color is filled and without gradient. Subject effect doesn't show in this case.
The effect basically looks like when changing tab, the new Navigation Bar background doesn't clear right away, and keeps the background from the previous Navigation Bar for 0.3 seconds before new one Navigation Bar background is rendered.
I spent quite some time on changing every possible setting, in code as well as storyboard ... no success so far.
Any ideas how to disable this undesired animation?
If I put the phone flat on a table, the left and right swipe gestures is not working but up and down gestures works.
Only when I put the iPhone to some vertical degree, the left and right swipe works.
Tested on 2 iPhone 7 Plus and 2 iPhone 13.
Anyone has similar experience? If yes, why?
Running an existing Xcode project in an iPad OS 18 simulator is automatically using the newly introduced tab bar view, moved from the bottom to the top.
Unfortunately, the isEnabled property on a tar bar item is no longer honored.
In Xcode's Storyboard builder, some tab bar items are initially disabled. (can't add a screenshot here, I will try to do that after posting)
The iPad OS 17 simulator shows them correctly as disabled and any user interaction is suppressed as expected.
The iPad OS 18 simulator shows them as active and they can be selected. Also setting them to disabled inside of the UITabBarViewController doesn't work:
for item in self.tabBar.items! {
if item.tag != 99 {
item.isEnabled = false
}
}
They stay enabled and selectable.
As a workaround, I implemented the UITabBarViewControllerDelegate and overrode this method:
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
if Global.shared.accessToken == nil {
if viewController is LoginViewController || viewController is SettingsViewController {
return true
} else {
return false
}
}
return true
}
The user can no longer select the tabs, however, there is no visual indicator that they are not selectable.
I cannot find any indication in the release notes or documentation, that this behavior is intentional. So I assume this is a bug.
Starting with iOS 18, there is a change in how the transition from an underlying view to a UIDocumentInteractionController’s preview view is animated. The transition now scales down the size of the content within the controller’s view, using the center point of the root view as the base of the transformation. This results in a smaller, compressed view centered within the root view, revealing the root view’s background, which is typically white. Even if this background color is adjusted to match elements like the navigation bar, the transformed view has non-rounded corners.
I have not tested this behavior when presenting a UIDocumentInteractionController from a SwiftUI view.
My question to the UIKit framework developers: Is this new behavior of UIDocumentInteractionController an intentional feature, a feature with bugs, or just a bug?
Currently, I have achieve shadow and corner effect for UICollectionViewListCell, using the following code.
UICollectionViewListCell
class NoteCell: UICollectionViewListCell {
override func awakeFromNib() {
super.awakeFromNib()
initShadow()
initCorner()
}
private func updateShadowColor() {
// Determine the shadow color based on the current interface style
let shadowUIColor = UIColor.label
self.layer.shadowColor = shadowUIColor.cgColor
}
private func initShadow() {
// https://www.hackingwithswift.com/example-code/uikit/how-to-add-a-shadow-to-a-uiview
self.layer.shadowOpacity = 0.3
self.layer.shadowOffset = CGSize(width: 0.5, height: 0.5)
self.layer.shadowRadius = 2
self.layer.masksToBounds = false
self.updateShadowColor()
// Remove the following two lines if you experience any issues with shadow rendering:
self.layer.shouldRasterize = true
self.layer.rasterizationScale = UIScreen.main.scale
}
private func initCorner() {
var backgroundConfig = UIBackgroundConfiguration.listPlainCell()
backgroundConfig.backgroundColor = .systemBackground
backgroundConfig.cornerRadius = 16
self.backgroundConfiguration = backgroundConfig
}
layout
private func layoutConfig() -> UICollectionViewCompositionalLayout {
let layout = UICollectionViewCompositionalLayout { section, layoutEnvironment in
var config = UICollectionLayoutListConfiguration(appearance: .plain)
config.headerMode = .none
config.footerMode = .none
config.showsSeparators = false
config.headerTopPadding = 0
config.backgroundColor = nil
config.trailingSwipeActionsConfigurationProvider = { [weak self] indexPath in
guard let self = self else { return nil }
// Knowing what we are tapping at.
var snapshot = dataSource.snapshot()
let sectionIdentifier = snapshot.sectionIdentifiers[indexPath.section]
let itemIdentifiers = snapshot.itemIdentifiers(inSection: sectionIdentifier)
let itemIdentifier: NoteWrapper = itemIdentifiers[indexPath.item]
let deleteHandler: UIContextualAction.Handler = { action, view, completion in
completion(true)
// TODO:
//snapshot.reloadItems([itemIdentifier])
}
let deleteAction = UIContextualAction(style: .normal, title: "Trash", handler: deleteHandler)
var swipeActionsConfiguration = UISwipeActionsConfiguration(actions: [
deleteAction,
])
deleteAction.image = UIImage(systemName: "trash")
deleteAction.backgroundColor = UIColor.systemRed
swipeActionsConfiguration.performsFirstActionWithFullSwipe = false
return swipeActionsConfiguration
}
// https://developer.apple.com/forums/thread/759987
let layoutSection = NSCollectionLayoutSection.list(using: config, layoutEnvironment: layoutEnvironment)
layoutSection.interGroupSpacing = 16 // Distance between item.
layoutSection.contentInsets = NSDirectionalEdgeInsets(
top: 16, // Distance between 1st item and its own header.
leading: 16,
bottom: 16, // Distance of last item and other header/ bottom edge.
trailing: 16
)
return layoutSection
}
return layout
}
This is the outcome.
However, when I perform swipe action, the shadow effect is gone.
Do you have any idea how I can resolve such? Thanks.
I use @Binding to sync data between SwiftUI component state and UITable state.
my observations:
while reordering @State variable of the TestView is updating, it can be checked by taping the button
inside the table the data is not updating. 'log2' is always the same on reorder and which is more important the app crashes when I try to remove item.
What to I missing?
import SwiftUI
import UIKit
struct TestView: View {
@State var items = ["item 1", "item 2", "item 3", "item 4", "item 5"]
var body: some View {
VStack {
Button("Print Items") { print("log1", items) }
ReorderableListView(
items: $items
) { item in
Text(item)
}
}
}
}
private struct ReorderableListView<Content: View>: UIViewControllerRepresentable {
@Binding var items: [String]
let content: (String) -> Content
class Coordinator: NSObject, UITableViewDataSource, UITableViewDelegate {
var parent: ReorderableListView
init(parent: ReorderableListView) {
self.parent = parent
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print("log2", parent.items)
return parent.items.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
let hostingController = UIHostingController(rootView: parent.content(parent.items[indexPath.row]))
hostingController.view.backgroundColor = .clear
cell.contentView.subviews.forEach { $0.removeFromSuperview() }
cell.contentView.addSubview(hostingController.view)
cell.separatorInset = UIEdgeInsets(top: 0, left: 15, bottom: 0, right: 15)
if indexPath.row == self.parent.items.count - 1 {
cell.separatorInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: .greatestFiniteMagnitude)
}
hostingController.view.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
hostingController.view.topAnchor.constraint(equalTo: cell.contentView.topAnchor),
hostingController.view.bottomAnchor.constraint(equalTo: cell.contentView.bottomAnchor),
hostingController.view.leadingAnchor.constraint(equalTo: cell.contentView.leadingAnchor),
hostingController.view.trailingAnchor.constraint(equalTo: cell.contentView.trailingAnchor)
])
return cell
}
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
let movedObject = parent.items.remove(at: sourceIndexPath.row)
parent.items.insert(movedObject, at: destinationIndexPath.row)
}
func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
parent.items.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .automatic)
}
}
}
func makeCoordinator() -> Coordinator {
Coordinator(parent: self)
}
func makeUIViewController(context: Context) -> UITableViewController {
let tableViewController = UITableViewController()
tableViewController.tableView.dataSource = context.coordinator
tableViewController.tableView.delegate = context.coordinator
tableViewController.tableView.register(CustomTableViewCell.self, forCellReuseIdentifier: "Cell")
tableViewController.tableView.isEditing = true
return tableViewController
}
func updateUIViewController(_ uiViewController: UITableViewController, context: Context) {
uiViewController.tableView.reloadData()
}
}
private class CustomTableViewCell: UITableViewCell {
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
override func layoutSubviews() {
super.layoutSubviews()
superview?.subviews.filter({ "\(type(of: $0))" == "UIShadowView" }).forEach { (sv: UIView) in
sv.removeFromSuperview()
}
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
#Preview {
TestView()
}
Hello everyone!
I was implementing a MFMessageComposeViewController to send messages.
Currently I'm observing behaviour that attachments button is always disabled. But thing is that I'm showing MFMessageComposeViewController only when canSendText() && canSendAttachments() are true.
if MFMessageComposeViewController.canSendText() && MFMessageComposeViewController.canSendAttachments() {
let composeVC = MFMessageComposeViewController()
composeVC.messageComposeDelegate = self
composeVC.body = "Test message"
self.present(composeVC, animated: true, completion: nil)
}
I've checked that mms are enabled.
I found iPadOS18 displayed navigation bar incorrectly when transition from screen with hidden navigation bar to screen that show navigation bar.
I have 2 ViewController: FirstViewController and SecondViewController.
FirstViewController navigationBar set isHidden to be true (hidden) and
SecondViewController navigationBar set isHidden to be false (showing).
When transition from FirstViewController to SecondViewController, the navigation bar is displayed incorrectly as shown in picture below:
Actual
Expected
Note
I set hide navigation bar in viewWillAppear() in both ViewController
override func viewWillAppear(_ animated: Bool) {
navigationController?.setNavigationBarHidden(..., animated: true)
}
source code: https://github.com/ornthita/TestTabbar
I'm facing an accessibility issue, where when I call UIViewController.addChild(_:) and pass in another instance of a UIViewController, the VoiceOver focus is jumping to the "Back" button in the navigation bar. How might one go about avoid this behaviour and having the accessibility/voiceover focus remain where it was at the time of adding the child?