Construct and manage graphical, event-driven user interfaces for iOS or tvOS apps using UIKit.

UIKit Documentation

Posts under UIKit subtopic

Post

Replies

Boosts

Views

Activity

iPadOS Floating Tab Bar Items (unselected) use Black Text - Unreadable with App Black Background (Dark Mode): UIKit App
Reference Feedback FB19152594 Occurs with my 3rd Party UIKit App called "Lifeorities". Latest occurrence was 7/27/25 at 13:49 pm. Launch app (actual device running iPadOS 26 or iPadOS 26 simulator) Initial screen displays view content and floating tab bar at top of screen (both portrait orientation and landscape). Floating tab bar items respond to liquid glass effect (but liquid glass appearance of the whole tab bar doesn't comply with new glass pill shaped tab bar area). Selected tab bar item obeys selected app designated color (assets). Unselected tab bar items are using black text which is unreadable on app background which used dark mode as default (as intended). Selecting another tab bar item shows the liquid glass effect as you navigate to the new tab bar item and shows the app designated color (assets). Previous tab bar item that was selected, now is unselected and shows black text. NOTE: iOS tab bar items work fine (show white foreground color as desired for unselected tab bar items).
0
1
79
Aug ’25
Xcode_26_beta_4 iOS 26 func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView?
It looks like we're encountering a similar hitTest issue to what we had with iOS Xcode 16 + iOS 18. When running Xcode 26 + iOS 26, rootViewController?.view.subviews is returning an empty array, even though the views are clearly present in the hierarchy. Last year, we "fixed" this issue using the code attached, but it doesn't seem to work anymore with iOS 26. Any suggestions would be greatly appreciated! private class PassthroughWindow: UIWindow { override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { guard let hitView = super.hitTest(point, with: event), let rootView = rootViewController?.view else { return nil } if #available(iOS 18, *) { for subview in rootView.subviews.reversed() { let convertedPoint = subview.convert(point, from: rootView) if subview.hitTest(convertedPoint, with: event) != nil { return hitView } } return nil } else { return hitView == rootView ? nil : hitView } } }
Topic: UI Frameworks SubTopic: UIKit
2
3
113
Aug ’25
UIBarButtonItem alignment in UIToolbar on iOS 26 in UIDesignRequiresCompatibility mode
The screenshot is showing the same app deployed using Xcode version 26.0 beta 4 (17A5285i) on iOS 18.5 and on iOS 26.0. In iOS 26 beta 4 on the right the spacing of the UIBarButtonItem elements does not look good: The buttons are created like so: colorButtonText = [[UIBarButtonItem alloc] initWithImage:[UIImage systemImageNamed:@"paintbrush"] style:UIBarButtonItemStylePlain target:self action:@selector(drawingActionColor:)]; //... [drawingToolbarText setItems:@[colorButtonText, ...]]; Is this a known issue with the current iOS 26? Am I doing something wrong?
0
2
198
Aug ’25
XCode 26 beta 4 search bar issue
I have a standard list view controller that has a UISearchController set up in the list's navigationItem. When built on Xcode 26 beta 4 the search bar does not appear. It's not present in the view hierarchy. On previous versions it appears, especially on Xcode 16.4. Is this a known issue? Haven't managed to find it anywhere. Also what could be the potential workaround?
1
0
82
Aug ’25
Trying to use UIScrollEdgeElementContainerInteraction
I have a UIKit app with a custom navigation controller. I want my view title to go up into the navigation bar when the user scrolls down the screen. It looks like UIScrollEdgeElementContainerInteraction should do what I want, but I am having trouble using it. Below is a sample, where a header view represents a title. I added the interaction to the header view, but it seems to have no effect. Am I missing a step? Perhaps I misunderstand what this is supposed to do, or perhaps I do not understand the preconditions to make this work. I am hoping someone can tell me what I am doing wrong, or point me to some working sample code. Thank you. John class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { var headerView: UIVisualEffectView! var tableView: UITableView! var interaction: UIScrollEdgeElementContainerInteraction! override func viewDidLoad() { super.viewDidLoad() self.tableView = UITableView() self.tableView.translatesAutoresizingMaskIntoConstraints = false self.tableView.topEdgeEffect.style = .soft self.tableView.delegate = self self.tableView.dataSource = self self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell") self.view.addSubview(self.tableView) self.view.addConstraints([ self.tableView.topAnchor.constraint(equalTo: self.view.topAnchor), self.tableView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor), self.tableView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor), self.tableView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor), ]) self.headerView = UIVisualEffectView(effect: UIGlassEffect(style: .regular)) self.headerView.translatesAutoresizingMaskIntoConstraints = false self.headerView.backgroundColor = .green self.view.addSubview(self.headerView) self.view.addConstraints([ self.headerView.topAnchor.constraint(equalTo: self.view.topAnchor), self.headerView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor), self.headerView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor), self.headerView.heightAnchor.constraint(equalToConstant: 100.0), ]) let label = UILabel() label.translatesAutoresizingMaskIntoConstraints = false label.text = "my text" self.headerView.contentView.addSubview(label) self.headerView.contentView.addConstraints([ label.centerXAnchor.constraint(equalTo: self.headerView.contentView.centerXAnchor), label.centerYAnchor.constraint(equalTo: self.headerView.contentView.centerYAnchor), ]) self.interaction = UIScrollEdgeElementContainerInteraction() self.interaction.scrollView = self.tableView self.interaction.edge = .top self.headerView.addInteraction(self.interaction) } func numberOfSections(in tableView: UITableView) -> Int { return 1 } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 100 } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = self.tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) cell.textLabel?.text = "row \(indexPath.row + 1)" return cell } }
Topic: UI Frameworks SubTopic: UIKit Tags:
7
0
150
Aug ’25
How to fix the gestureRecognizer over PDFKit breaking the paging in the new ios26 version?
I had project going great, where i needed to do stuff with pdfs, drawing on top them etc. Since apple is all closed sourced i needed to become a bit hacky. Anyways, i have a problem since the new ios 26 update which breaks the behaviour. I simplified the code very much into a demo project, where you can quickly see what's wrong. When swiping left to go to the next page, it does change the page etc in the pdf Document, but visually nothing happens. I am stuck on the first page. I dont know what to do, tried a lot of things, but nothing works. Anyone skilled enough to help me out? import UIKit import PDFKit import SwiftUI class PDFViewController: UIViewController { var pdfView: PDFView! var gestureHandler: GestureHandler! override func viewDidLoad() { super.viewDidLoad() setupPDFView() setupGestureHandler() loadPDF() } private func setupPDFView() { pdfView = PDFView(frame: view.bounds) // Your exact configuration pdfView.autoScales = true pdfView.pageShadowsEnabled = false pdfView.backgroundColor = .white pdfView.displayMode = .singlePage view.addSubview(pdfView) // Setup constraints pdfView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ pdfView.topAnchor.constraint(equalTo: view.topAnchor), pdfView.leadingAnchor.constraint(equalTo: view.leadingAnchor), pdfView.trailingAnchor.constraint(equalTo: view.trailingAnchor), pdfView.bottomAnchor.constraint(equalTo: view.bottomAnchor) ]) } private func setupGestureHandler() { gestureHandler = GestureHandler(pdfView: pdfView) gestureHandler.setupSwipeGestures(on: view) } private func loadPDF() { if let path = Bundle.main.path(forResource: "sonate12", ofType: "pdf"), let document = PDFDocument(url: URL(fileURLWithPath: path)) { pdfView.document = document } else { print("Could not find sonate12.pdf in bundle") } } } class GestureHandler { private weak var pdfView: PDFView? init(pdfView: PDFView) { self.pdfView = pdfView } func setupSwipeGestures(on view: UIView) { // Left swipe - go to next page let leftSwipe = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipe(_:))) leftSwipe.direction = .left view.addGestureRecognizer(leftSwipe) // Right swipe - go to previous page let rightSwipe = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipe(_:))) rightSwipe.direction = .right view.addGestureRecognizer(rightSwipe) } @objc private func handleSwipe(_ gesture: UISwipeGestureRecognizer) { guard let pdfView = pdfView, let document = pdfView.document, let currentPage = pdfView.currentPage else { print("🚫 No PDF view, document, or current page available") return } let currentIndex = document.index(for: currentPage) let totalPages = document.pageCount print("📄 Current state: Page \(currentIndex + 1) of \(totalPages)") print("👆 Swipe direction: \(gesture.direction == .left ? "LEFT (next)" : "RIGHT (previous)")") switch gesture.direction { case .left: // Next page guard currentIndex < document.pageCount - 1 else { print("🚫 Already on last page (\(currentIndex + 1)), cannot go forward") return } let nextPage = document.page(at: currentIndex + 1) if let page = nextPage { print("➡️ Going to page \(currentIndex + 2)") pdfView.go(to: page) pdfView.setNeedsDisplay() pdfView.layoutIfNeeded() // Check if navigation actually worked DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { if let newCurrentPage = pdfView.currentPage { let newIndex = document.index(for: newCurrentPage) print("✅ Navigation result: Now on page \(newIndex + 1)") if newIndex == currentIndex { print("⚠️ WARNING: Page didn't change visually!") } } } } else { print("🚫 Could not get next page object") } case .right: // Previous page guard currentIndex > 0 else { print("🚫 Already on first page (1), cannot go back") return } let previousPage = document.page(at: currentIndex - 1) if let page = previousPage { print("⬅️ Going to page \(currentIndex)") pdfView.go(to: page) pdfView.setNeedsDisplay() pdfView.layoutIfNeeded() let bounds = pdfView.bounds pdfView.bounds = CGRect(x: bounds.origin.x, y: bounds.origin.y, width: bounds.width + 0.01, height: bounds.height) pdfView.bounds = bounds // Check if navigation actually worked DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { if let newCurrentPage = pdfView.currentPage { let newIndex = document.index(for: newCurrentPage) print("✅ Navigation result: Now on page \(newIndex + 1)") if newIndex == currentIndex { print("⚠️ WARNING: Page didn't change visually!") } } } } else { print("🚫 Could not get previous page object") } default: print("🤷‍♂️ Unknown swipe direction") break } } } struct PDFViewerRepresentable: UIViewControllerRepresentable { func makeUIViewController(context: Context) -> PDFViewController { return PDFViewController() } func updateUIViewController(_ uiViewController: PDFViewController, context: Context) { // No updates needed } } You can look at the code here as well: https://github.com/vallezw/swift-bug-ios26
0
1
124
Aug ’25
UIMainMenuSystem and MKMapView
I've added some menus to the new (mac-like) menu bar on the iPad App under iPadOS 26, which is working fine. However if the main view controller covers the whole screen and shows a fullscreen Map (MKMapView), the menu bar has a dark gradient as a background, which makes it extremely difficult to see the menu. I guess the iPadOS tries to put a semi-transparent layer between the view controller and the menu bar to make sure that the content of the view controller doesn't interfere with with the menubar and the menu is easy to read. But when the view controller shows a map, the system seems to get the colors for this transparent layer wrong. Is it possible to solve this, or is this still a bug of iPad OS 26? Interestingly, when I create a screenshot of the screen, this dark gradient which makes the menu bar unreadably is not included in the screenshot. So in the screenshot the menu is easy to read. Only on the real device, the menu bar is almost unreadably
1
0
119
Aug ’25
How can shadows and borders be used on a view that is set up with iOS 26 cornerConfiguration API and concentric values?
On UIKit, shadows and borders are used laid out using CALayer properties. This works great when using .cornerRadius as this can be applied to the layers displaying borders/shadows. With the addition of cornerConfiguration, which is done via UIView, what is the expected setup for making sure, for example, when a UIView is using a concentric behavior to its parent, that its shadows and borders are following the same corner radius for each side? Would it be correct to read the corner radius values on the UIView's layoutSubviews method and then apply those to the border/shadow properties?
Topic: UI Frameworks SubTopic: UIKit Tags:
1
0
121
Aug ’25
Dragging window on iPad from near the top
By default, a window on iPadOS 26 can be dragged by touching and dragging the top ~30 points of that window. If the window's root view controller is a UINavigationController with a navigation bar, the window can be dragged by touching and dragging anywhere in that navigation bar. In Apple Calendar, I can drag a window anywhere above the grid of weeks and days. I have an app with a custom navigation controller. My navigation controller is not a subclass of UINavigationController. How can I define what portion of the window should let the user drag that window across the screen on iPad?
Topic: UI Frameworks SubTopic: UIKit Tags:
2
0
88
Aug ’25
UITabBarController, menu bar and first responder
I'm using a standard UITabBarController on iPad. When first selecting any tab, the corresponding menu bar items are grayed out for this view controller. It's only when I tap any button in that view controller, like in the toolbar, that the view controller truly becomes the first responder (you can see the sidebar selection turns to gray from blue), enabling those menu bar items. Am I doing something wrong here? A video of the issue can be found here: https://mastodon.social/@nicoreese/114949924393554961 AppDelegate: ... builder.insertChild(MenuController.viewModeMenu(), atStartOfMenu: .view) class func viewModeMenu() -> UIMenu { let listViewModeCommand = UICommand( title: String(localized: "As List"), image: UIImage(systemName: "list.bullet"), action: #selector(GamesViewController.setListViewMode), propertyList: SettingsService.ViewMode.list.rawValue ) ... let viewModeMenu = UIMenu( title: "", image: nil, identifier: .viewModeMenu, options: .displayInline, children: [listViewModeCommand...] ) return viewModeMenu } GamesViewController: @objc func setListViewMode() { updateViewMode(.list) } I can do this, but then the sidebar selection instantly turns gray, which looks odd and other system apps do not behave this way. override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) becomeFirstResponder() } override var canBecomeFirstResponder: Bool { return true }
Topic: UI Frameworks SubTopic: UIKit Tags:
5
0
164
Jul ’25
Replacing the Preferences item in a menu bar
Per default the menu bar on iPad includes an application menu named after your app which includes a Preferences action. That one opens the Settings app to your app settings page. I do not really populate that with options and instead have my own settings UI accessible in my app using toolbar items. What's the best approach to handle this with the menu bar? I've tried replacing the default Preferences item but that only works if I do not use its shortcut, which I would like to preserve. Another solution would be to append another Settings item for my UI, which would look weird and confusing, but seems to be the recommended way from the HIG. Reserve the YourAppName > Settings menu item for opening your app’s page in iPadOS Settings. If your app includes its own internal preferences area, link to it with a separate menu item beneath Settings in the same group. Place any other custom app-wide configuration options in this section as well. I take it there is no way to replace it then?
Topic: UI Frameworks SubTopic: UIKit Tags:
3
0
116
Jul ’25
iPad menu bar and multiple windows
I'm trying to support the new menu bar in iPadOS 26. In AppDelegate I do this. I want to this to be a global command, which can work regardless of which view controller is currently visible, so I let the AppDelegate handle the selector (if there's a better way let me know). UIMainMenuSystem.shared.setBuildConfiguration(config) { builder in let createCollectionCommand = UIKeyCommand( title: String(localized: "Create Collection"), image: UIImage(systemName: "folder.badge.plus"), action: #selector(AppDelegate.showCreateCollectionViewController), input: "c", modifierFlags: .control ) builder.insertElements([createCollectionCommand], atEndOfMenu: .file) } This works mostly. A problem arrises when I have multiple windows open at the same time. I need a way to determine the currently active window scene from AppDelegate to display a sheet on that window's root view controller. There's stuff like this, but unfortunately all visible windows have activationState == .foregroundActive, so I cannot use that. guard let scene = UIApplication.shared.connectedScenes.first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene else { return } So, how do I do multi-window global commands? I'm basically looking for something like the "Create Playlist" command in the Music app.
Topic: UI Frameworks SubTopic: UIKit Tags:
2
0
102
Jul ’25
UITabBar hitTest method is not triggered when click button that is a subview of UITabBar and the subview frame is beyond UITabBar when using Xcode26 build app on OS 26
In our project, we defined a CustomTabBar that inherits UITabBar, and we add some subviews and these subviews' frame is beyond UITabBar, see below picture(a beyond area button, this button is a subview of UITabBar, but frame is out of UITabBar's area): and in order to let this button response to click action, we override the UITabBar's hitTest method, this works well below OS 26 with Xcode version below 26: override public func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { let pointInCollectionView = self.beyondAreaButton.convert(point, from: self) if self.beyondAreaButton.bounds.contains(pointInCollectionView) { return self.beyondAreaButton.hitTest(pointInCollectionView, with: event) } return super.hitTest(point, with: event) } but when using Xcode26 build app on OS 26, I noticed the UITabBar is wrapped by a UIKit._UITabBarContainerView and UIKit._UITabBarContainerWrapperView, and it can not trigger the hitTest method. since the hitTest is not triggered, so the button action is no chance to trigger too. Any suggestions to solve this problem, thank you~ And I have file a feedback assistant: FB19252973
1
0
103
Jul ’25
Best Practice for Resizing UITableViewCell Containing WKWebView with DiffableDataSource
Hi everyone, I’m currently working on a UITableView setup that uses UITableViewDiffableDataSource. Each cell contains two views: A UILabel for a title A WKWebView that loads dynamic HTML content My Current Approach: On initial load, I let all cells render with default height. As each WKWebView finishes loading, I calculate its content height using JavaScript and store this height in a [String: CGFloat] dictionary keyed by a unique identifier for each WebView. I then call tableView.performBatchUpdates to trigger a layout update and resize the cell. When the same cell index and data are shown again, I retrieve the cached height from the dictionary and apply it as a constraint on the WKWebView before loading its content. This mostly works, but occasionally, there are visual glitches — such as flickering during scrolling or incorrect cell heights temporarily shown before the height is re-applied. My Questions: Is this a recommended or sustainable way for handling WKWebView inside a UITableViewCell, especially with DiffableDataSource? Are there any known best practices or alternatives to manage dynamic web content heights more smoothly in table cells? Is it possible that the glitches are caused by layout timing issues or reentrancy of height calculation and rendering? Any suggestions, refinements, or architectural recommendations would be greatly appreciated. Thanks in advance!
0
0
39
Jul ’25
Three dots button overlaps content
I’m working on an old iPad app with a concept that only works in landscape mode. The app’s content is not dynamic and can’t be rearranged depending on the window size. To ensure a good user experience, I set the UIRequiresFullScreen key to true in the Info.plist. Despite this, it’s still possible in iPadOS 26 to resize an app that requires fullscreen. When this happens, the three-dot button overlaps the content, and elements placed in the top-left corner become hard to access. Is there a way to detect when an app is resized and/or when the three-dot button overlaps the app? The UIScreen / UIScene or UIWindow bounds don’t seem to change when UIRequiresFullScreen is set to true. Also, UIScene.isFullscreen always returns false.
1
0
136
Jul ’25
Alignment of navigationItem.titleView in iOS 26?
I'm in the process of updating an app for iOS 26 and I've run into some behavior that I don't quite understand. I have a view controller that is embedded in a navigation controller. That VC currently uses a UISegmentedControl (with 3 segments) for its navigation item title view. In iOS 17 and 18, this works well. There is one right bar button item when the first or second segment is selected and no bar button items at all when the third segment is selected. On iOS 17 and 18, the title view always appears centered. When I run this app on the iOS 26 beta 4 simulator, the title view appears to be left-aligned (instead of centered) when the first or second segment is selected (and the one right bar button item exists) but it is centered when the third segment is selected and there is no right bar button item. I thought maybe this was something related to a UISegmentedControl so I created a new custom view to use for the title view instead and it is behaving the same way. Is this a behavior change in iOS 26?
Topic: UI Frameworks SubTopic: UIKit
1
0
118
Jul ’25