I have a couple of (older) UIKit-based Apps using UISplitViewController on the iPad to have a two-column layout. I'm trying to edit the App so it will shows the left column as sidebar with liquid glass effect, similar to the one in the "Settings" App of iPadOS 26. But this seems to be almost impossible to do right now.
"out of the box" the UISplitViewController already shows the left column somehow like a sidebar, with some margins to the sides, but missing the glass effect and with very little contrast to the background. If the left column contains a UITableViewController, I can try to get the glass effect this way within the UITableViewController:
tableView.backgroundColor = .clear
tableView.backgroundView = UIVisualEffectView(effect: UIGlassContainerEffect())
It is necessary to set the backgroundColor of the table view to the clear color because otherwise the default background color would completely cover the glass effect and so it's no longer visible.
It is also necessary to set the background of all UITableViewCells to clear.
If the window is in the foreground, this will now look very similar to the sidebar of the Settings App.
However if the window is in the back, the sidebar is now much darker than the one of the Settings App. Not that nice looking, but for now acceptable.
However whenever I navigate to another view controller in the side bar, all the clear backgrounds destroy the great look, because the transition to the new child controller overlaps with the old parent controller and you see both at the same time (because of the clear backgrounds).
What is the best way to solve these issues and get a sidebar looking like the one of the Settings App under all conditions?
UIKit
RSS for tagConstruct and manage graphical, event-driven user interfaces for iOS or tvOS apps using UIKit.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
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?
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
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?
The Apple documentation for [UIViewController willMoveToParentViewController:] states,
Called just before the view controller is added or removed from a container view controller.
Hence, the view controller being popped should appear at the top of the navStack when willMoveToParentViewController: is called.
In iPadOS 16 and 17 the view controller being popped appears at the top of the navStack when willMoveToParentViewController: is called.
In iPadOS 18 the view controller being popped has already been (incorrectly) removed from the navStack. We confirmed this bug using iPadOS 18.2 as well as 18.0.
Our app relies upon the contents of the navStack within willMoveToParentViewController: to track the user's location within a folder hierarchy.
Our app works smoothly on iPadOS 16 and 17. Conversely, our customers running iPadOS 18 have lost client data and corrupted their data folders as a result of this bug! These customers are angry -- not surprisingly, some have asked for refunds and submitted negative app reviews.
Why doesn't willMoveToParentViewController: provide the correct navStack in iPadOS 18.2?
Starting on iOS 26 Beta 3, any UIVisualEffectView using a UIGlassEffect will have a default corner radius that cannot be modified by using UIVisualEffectView's layer.cornerRadius. This was working on Beta 1 and Beta 2.
On WWDC25 "Build a UIKit app with the new design", a UIVisualEffectView property called cornerConfiguration is used as example for changing the effect's corner radius, but this property does not seem to be available on any of the beta versions.
Is there any other way to update the UIGlassEffect corner radius on UIKit?
My app support ringout feature, when set Ringout, all the calls in my app will go to native, by using tel://xxx.
But when my app set as the default calling app by the user. Then when user make a call from Contact, it will jump to my app, but app will will route this call to native.
So there is a issue for this, then the quesion is:
How to check if my app is set as default calling app?
We are currently developing an enterprise iOS application and are in the process of implementing Data Leakage Protection (DLP) features. As part of this effort, we need to control the available actions and target applications presented within the UIActivityViewController.
Specifically, we would like to programmatically filter or restrict certain activities and destination apps shown in the share sheet based on user-specific permissions. These permissions will be dynamically evaluated and updated at runtime.
This type of functionality is supported by the Microsoft Intune SDK. However, our objective is to implement this behavior natively within our application without relying on any third-party libraries.
Could you please advise on the recommended approach or available APIs to achieve this level of control over the UIActivityViewController?
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
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?
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.
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!
I am creating 500 textfield widgets and then updating them and all their 40 properties at once. I require to update all 500 widgets with their properties at once as it is a usecase in our app, so pooling and showing only those that will be on screen won't really help in this case.
I have found that for updating all these 500 textfield widgets with their 40 properties, the time taken is 80 to 100 milliseconds.
However, if I update the non-string properties like .text, then it comes down to half which is 40 to 50 milliseconds.
Wanted to know if there was a far more quicker or optimized way to do this?
The following snippet of code shows what I am doing:
@objc private func handleImmediateMode() {
let startTime = CFAbsoluteTimeGetCurrent()
for (index, textField) in retainedInputFields.enumerated() {
updateAllProperties(for: textField, index: index)
}
let endTime = CFAbsoluteTimeGetCurrent()
print("Immediate Mode -- (500 fields, 40 props): \( (endTime - startTime) * 1000) ms")
}
In the above code, I have already created the 500 textfield widget, and then in updateAllProperties () function I am passing the textfield widget to it and then updating the 40 properties that the widget has.
Particularily, the following properties:
textField.placeholder = "Input Field (index)"
UILabel().text
Seem to be adding the extra 40 - 50 milliseconds.
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.
I disable 4 or 5 Finger Gestures on Settings.app > Multi-tasking and Gestures.
But in the third-party apps, 4-5 finger touches are sometimes immediately cancelled.
Especially, 4-5 finger swipe gesture.
I filed this issue to FB19226717.
I develop Piano instrument app. 4 or 5 finger touches are required for that kind of apps. Please fix this, Apple.
when using CNContactViewController to present a contact detail info, the system CNContactViewController appear some UI issues.
On iOS 26, the Poster avatar overlaps with the title "Edit device contact"
On iPadOS26 with device(not simulator), when click 'Add photo', the CNContactViewController will auto dismiss, and the console output some error log:
below are the sample code:
AppDelegate.swift:
import UIKit
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
let window: UIWindow = UIWindow()
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let vc = SplitViewController(primary: TabBarViewController(), secondary: ViewController())
window.rootViewController = vc
window.makeKeyAndVisible()
return true
}
}
SplitViewController.swift:
import UIKit
class SplitViewController: UISplitViewController {
init(primary: UIViewController, secondary: UIViewController) {
super.init(nibName: nil, bundle: nil)
preferredDisplayMode = .oneBesideSecondary
presentsWithGesture = false
delegate = self
viewControllers = [primary, secondary]
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
}
}
extension SplitViewController: UISplitViewControllerDelegate {
}
TabBarViewController.swift:
import UIKit
class BaseViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
}
class HomeViewController: BaseViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .red
navigationItem.title = "Home"
tabBarItem = UITabBarItem(title: "Home", image: UIImage(systemName: "house"), tag: 0)
}
}
class TabBarViewController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
let homeVC = HomeViewController()
let homeNav = UINavigationController(rootViewController: homeVC)
viewControllers = [homeNav]
ContactManager.shared.getAllContactIdentifiers()
}
}
ViewController.swift:
import UIKit
import Contacts
import ContactsUI
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemPink
let button = UIButton(frame: .zero)
button.backgroundColor = .orange
button.setTitle("show contact", for: .normal)
button.addTarget(self, action: #selector(showContactInfo), for: .touchUpInside)
button.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(button)
button.widthAnchor.constraint(equalToConstant: 200).isActive = true
button.heightAnchor.constraint(equalToConstant: 60).isActive = true
button.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
button.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
}
@objc private func showContactInfo() {
print("showContactInfo")
let identifier = ContactManager.shared.identifiers[0]
let currentContact = try? CNContactStore().unifiedContact(withIdentifier: identifier, keysToFetch: [CNContactViewController.descriptorForRequiredKeys()])
guard let contact: CNMutableContact = currentContact?.mutableCopy() as? CNMutableContact else {
return
}
let vc = CNContactViewController(forNewContact: contact)
vc.delegate = self
vc.title = "Edit Device Contact"
vc.allowsActions = false
vc.contactStore = CNContactStore()
let navigationVC: UINavigationController = UINavigationController(rootViewController: vc)
let appDelegate = UIApplication.shared.delegate as? AppDelegate
appDelegate?.window.rootViewController?.present(navigationVC, animated: true, completion: nil)
}
}
extension ViewController: CNContactViewControllerDelegate {
public func contactViewController(_ viewController: CNContactViewController, didCompleteWith contact: CNContact?) {
viewController.dismiss(animated: true, completion: nil)
}
}
In iOS 26 beta 4 (build from July 2025), there is a visual issue when using a UISplitViewController. Specifically, the text color of labels in the primary column does not adapt correctly to Dark Mode. This includes navigation bar titles and labels inside UITableViewCells. Regardless of system appearance settings, the text remains black, making it unreadable when the system switches to Dark Mode.
To reproduce this, create a new iOS project using UISplitViewController with the .doubleColumn style. In the primary column, embed a UIViewController that contains a navigation title using navigationItem.title, and a UITableView showing a list of items. Run the app on a device or simulator with iOS 26 beta 4. Then switch the system appearance to Dark Mode using Control Center and observe the interface.
The expected result is that all labels in the primary column, including the navigation title and table view cell labels, should automatically update to a light text color in Dark Mode. This behavior works correctly in iOS 18. However, the actual result is that all these labels remain black, leading to poor visibility in Dark Mode and ignoring the system’s appearance setting.
https://feedbackassistant.apple.com/feedback/19194379
The iOS 18 Zoom Transition animation is glitchy when the source view is a UICollectionViewCell and just after dismissing the Detail View, user swipes their finger on the the UICollectionView. The cell's animation appears glitchy as it's settling into its final position.
Steps to Reproduce:
Create a UICollectionView with a UICollectionViewCell as a source view for the Zoom Transition
Implement iOS 18 Zoom Transition using preferredTransition = .zoom { context in return cell }
Present a detail view by tapping a UICollectionViewCell (zoom in works correctly)
Dismiss the detail view by performing a swift/quick swipe gesture up or down in one fluid motion
Important to note: This issue does not reproduce if you slowly scroll the scroll view by holding your finger down on it. It only reproduces if you swipe and lift your finger up. I've attached the video showcasing the issue: https://github.com/davor-storyteller/ios-18-zoom-transition-sample/issues/1
Expected Behavior:
The detail view should smoothly zoom back into the original collection view cell position with a fluid animation, regardless of swipe gesture.
Actual Behavior:
When using swift swipe gestures, the zoom transition back to the collection view cell appears glitchy - the cell animation may appear jerky, incorrectly positioned, or have visual artifacts during the transition.
Here is a link to the Github repository with sample code where this issue is reproducible: https://github.com/davor-storyteller/ios-18-zoom-transition-sample
Topic:
UI Frameworks
SubTopic:
UIKit
Hi all,
I'm running into a UIKit issue specific to iOS 26 (Xcode 26 Beta 4) where UIAlertAction buttons that are disabled using .isEnabled = false do not appear visually disabled. The alert still shows the action with full opacity and default styling, making it look like the button is tappable — even though it isn't.
❗ Issue:
On iOS 26, disabled actions in UIAlertController no longer appear dimmed or inactive. This is a visual regression compared to iOS 17 and earlier, where disabled actions would automatically appear grayed out and visually distinct.
Topic:
UI Frameworks
SubTopic:
UIKit
Hi all,
I'm running into a UIKit issue specific to iOS 26 (Xcode 26 Beta 4) where UIAlertAction buttons that are disabled using .isEnabled = false do not appear visually disabled. The alert still shows the action with full opacity and default styling, making it look like the button is tappable — even though it isn't.
❗ Issue:
On iOS 26, disabled actions in UIAlertController no longer appear dimmed or inactive. This is a visual regression compared to iOS 18 and earlier, where disabled actions would automatically appear grayed out and visually distinct.