I’ve encountered an aspect of the Liquid Glass effect in SwiftUI that seems a bit odd: the Liquid Glass interaction appears to ignore regular hit-testing behavior.
The following sample shows a button with hit testing disabled:
@main
struct LiquidGlassHitTestDemo: App {
var body: some Scene {
WindowGroup {
Button("Liquid") {
fatalError("Never called.")
}
.buttonStyle(.glassProminent)
.allowsHitTesting(false)
}
}
}
As expected, the button’s action is never called. However, the interactive glass effect still responds to touch events:
What’s even more surprising is that the UIKit equivalent behaves differently:
final class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let button = UIButton(
configuration: .prominentGlass(),
primaryAction: UIAction(
title: "Liquid",
handler: { action in
print("Never called.")
}
)
)
view.addSubview(button)
button.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
button.centerXAnchor.constraint(equalTo: view.centerXAnchor),
button.centerYAnchor.constraint(equalTo: view.centerYAnchor)
])
button.isUserInteractionEnabled = false
}
}
In this case, the effect is not interactive at all. Similarly, if a UIViewController’s root view overrides hitTest(_:with:) to always return nil, the Liquid Glass effect does not react to touch events whatsoever.
The only way I’ve found to “properly” disable the glass interactivity in SwiftUI is to use the .disabled(true) modifier. However, this also changes the button’s appearance, which is not always desirable.
Is this expected behavior, or could this be a bug? Am I missing something about how Liquid Glass interaction is implemented in SwiftUI?
UIKit
RSS for tagConstruct and manage graphical, event-driven user interfaces for iOS or tvOS apps using UIKit.
Posts under UIKit tag
200 Posts
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
When you set inputAccessoryView AND inputView you get unexpected system UI in between the two custom views
If anyone has a workaround for this I'd love to hear it.
See also: https://stackoverflow.com/questions/79818015/uitextfield-custom-inputaccessoryview-with-custom-inputview-in-ios-26
Red == inputAccessoryView
Blue == inputView
Glassy bit in between == bug?
//
// ViewController.swift
// Custom Keyboard
//
// Created by Lewis Smith on 19/02/2026.
//
import UIKit
class ViewController: UIViewController {
let textField = {
let textField = UITextField()
textField.translatesAutoresizingMaskIntoConstraints = false
textField.backgroundColor = .yellow
let inputAccessoryView = UIView(frame: CGRect(x: 0, y: 0, width: .zero, height: 70))
inputAccessoryView.backgroundColor = .red
let inputView = UIView(frame: CGRect(x: 0, y: 0, width: .zero, height: 70))
inputView.backgroundColor = .blue
// When you set inputAccessoryView AND inputView you get unexpected UI inbetweeen the two custom views
textField.inputAccessoryView = inputAccessoryView
textField.inputView = inputView
textField.becomeFirstResponder()
return textField
}()
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = .purple
self.view.addSubview(textField)
NSLayoutConstraint.activate([
textField.centerXAnchor.constraint(equalTo: view.centerXAnchor),
textField.centerYAnchor.constraint(equalTo: view.centerYAnchor),
textField.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
textField.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20),
])
}
}
My app start up has became horrid. It takes 1 minute to open SQLlite database for my rust core. Impossible to work...
I have Address Sanitizer, Thread Perf Checker and Thread Sanitizer disabled...
Any logical reason why applying .sharedBackgroundVisibility(.hidden) to a ToolbarItem would not remove the spacing allocated for glass border?
Thus causing any element utilizing this functionality to appear offset from the regular buttons.
Or is this yet another magical Apple experience I am not blessed enough to understand.
Hi everyone,
I’m running into a strange issue with UISearchController placement with iOS 26 SDK.
In one of my view controllers, I was able to move the search bar to the top of the navigation bar by setting:
navigationItem.searchController = searchController
navigationItem.hidesSearchBarWhenScrolling = false
navigationItem.preferredSearchBarPlacement = .stacked
This works as expected — the search bar is placed at the top.
However, in another view controller with almost identical configuration, the search bar always shows up at the bottom. If I delay the setup with DispatchQueue.main.async, it appears at the bottom; if I don’t, it doesn’t appear at all. Both VCs are wrapped in their own UINavigationController.
So my questions are:
Has anyone faced this issue where preferredSearchBarPlacement = .stacked is ignored?
Are there hidden requirements or limitations for placing the search bar at the top?
Why could the same setup behave differently in two controllers?
Any help or ideas would be appreciated!
Could you help me with resolving this issue, please.
I've got following trace:
ksmemory_notifyUnhandledFatalSignal
EXC_BAD_ACCESS (KERN_INVALID_ADDRESS)
Crashed: com.apple.main-thread
EXC_BAD_ACCESS KERN_INVALID_ADDRESS 0x000000000000002b
Crashed: com.apple.main-thread
0 KSCrash 0xbff8 ksmemory_notifyUnhandledFatalSignal + 12
1 KSCrash 0xcd6c handleSignal + 100
2 libsystem_platform.dylib 0x4178 _sigtramp + 56
3 libsystem_kernel.dylib 0x42f8 mach_msg2_internal + 76
4 libsystem_kernel.dylib 0x4214 mach_msg_overwrite + 428
5 libsystem_kernel.dylib 0x405c mach_msg + 24
6 CoreFoundation 0x46868 __CFRunLoopServiceMachPort + 160
7 CoreFoundation 0x1d848 __CFRunLoopRun + 1188
8 CoreFoundation 0x1ca6c _CFRunLoopRunSpecificWithOptions + 532
9 GraphicsServices 0x1498 GSEventRunModal + 120
10 UIKitCore 0x9ddf8 -[UIApplication _run] + 792
11 UIKitCore 0x46e54 UIApplicationMain + 336
12 UIKitCore 0x172938 -[UIScrollView contentInset] + 588
13 AppName 0xed9440 main + 4386804800 (AppDelegate.swift:4386804800)
14 ??? 0x189f76e28 (Missing)
It appears that a variable or object is attempting to access another object that has already been deallocated. Based on the stack trace, the issue was likely detected while layout was in progress.
Our analytics show this happens generally on app launch and occasionally during normal use.
Unfortunately, I couldn't gather additional diagnostic data. I tried to reproduce the issue using the Leaks tool and enabled runtime diagnostics (Address Sanitizer, Malloc Scribble, Zombies), but without success.
I may be overlooking something — any suggestions would be greatly appreciated.
Thank you in advance
Our app supports UIScene. As a result, launchOptions in application(_:didFinishLaunchingWithOptions:) is always nil.
However, the documentation mentions that UIApplication.LaunchOptionsKey.location should be present when the app is launched due to a location event.
Given that our app is scene-based:
How can we reliably determine whether the app was launched due to a location update, geofence, or significant location change?
Is there a recommended pattern or API to detect this scenario in a Scene-based app lifecycle?
This information is critical for us to correctly initialize location-related logic on launch.
Relevant documentation:
https://developer.apple.com/documentation/corelocation/cllocationmanager/startmonitoringsignificantlocationchanges()
I have a very simple custom collection view layout that supports self-sizing. When a cell is selected, I expand the cell by modifying its constraints. This change (and the resulting effect on the collection view layout) is animated using [self.collectionView.collectionViewLayout invalidateLayout] followed by [self.collectionView layoutIfNeeded] within an animation closure.
When you first tap on a cell, it expands smoothly as expected. When you tap on it again to contract it, however, its content jumps before it shrinks again. How can I fix this?
For what it’s worth, I’ve noticed that neither UICollectionViewFlowLayout nor UICollectionViewCompositionalLayout have this issue, which suggests I’m doing self-sizing incorrectly.
Here’s a screen recording demonstrating the issue. I’ve also put together a minimal sample project.
I’m using Xcode 26.2 and iOS 26.2.1.
I need to detect whether a view controller is presented in a popover or in fullscreen mode, as on iPhone.
I checked viewController.popoverPresentationController but it returns a non-nil value even on iPhone, when it's clearly not in a popover.
I then checked viewController.presentationController?.adaptivePresentationStyle but it returns .formSheet even when it's presented in a popover!?! Why?
This whole adaptive presentation thingie is a mess. Heck, viewController.presentationController returns _UIPageSheetPresentationController even when the view controller is in a UINavigationController, so not presented at all.
Anybody got any ideas?
There is no way to make an instance of UISegmentedControl transparent like it's done in Photos or Camera. Especially it looks wrong when segmented control is put to a Liquid Glass container.
Setting background colour to nil or clear does not help
If a transparent image is set as a background image for state and bar metrics, it kills liquid glass selection and segments started to look wrong
How can the standard gray-ish background can be removed?
[Submitted as FB21958289]
A minimal SwiftUI app logs framework warnings when a bottom bar Menu is used with the system search toolbar item. The most severe issue is logged as a console Fault (full logs below):
Adding 'UIKitToolbar' as a subview of UIHostingController.view is not supported and may result in a broken view hierarchy. Add your view above UIHostingController.view in a common superview or insert it into your SwiftUI content in a UIViewRepresentable instead.
This appears to be a framework-level SwiftUI/UIKit integration issue, not custom UIKit embedding in app code. The UI may still render, but the warnings indicate an internal hierarchy/layout conflict.
This occurs in simulator and physical device.
REPRO STEPS
Create a new project then replace ContentView with the code below.
Run the app.
The view uses NavigationStack + .searchable + .toolbar with:
ToolbarItem(placement: .bottomBar) containing a Menu
DefaultToolbarItem(kind: .search, placement: .bottomBar)
EXPECTED RESULT
No view hierarchy or Auto Layout warnings in the console.
ACTUAL RESULT
Console logs warnings such as:
"Adding 'UIKitToolbar' as a subview of UIHostingController.view is not supported..."
"Ignoring searchBarPlacementBarButtonItem because its vending navigation item does not match the view controller's..."
"Unable to simultaneously satisfy constraints..." (ButtonWrapper/UIButtonBarButton width and trailing constraints)
MINIMAL REPRO CODE
import SwiftUI
struct ContentView: View {
@State private var searchText = ""
@State private var isSearchPresented = false
var body: some View {
NavigationStack {
List(0..<30, id: \.self) { index in
Text("Row \(index)")
}
.navigationTitle("Toolbar Repro")
.searchable(text: $searchText, isPresented: $isSearchPresented)
.toolbar {
ToolbarItem(placement: .bottomBar) {
Menu {
Button("Action 1") { }
Button("Action 2") { }
} label: {
Label("Actions", systemImage: "ellipsis.circle")
}
}
DefaultToolbarItem(kind: .search, placement: .bottomBar)
}
}
}
}
CONSOLE LOG
Adding 'UIKitToolbar' as a subview of UIHostingController.view is not supported and may result in a broken view hierarchy. Add your view above UIHostingController.view in a common superview or insert it into your SwiftUI content in a UIViewRepresentable instead.
Ignoring searchBarPlacementBarButtonItem because its vending navigation item does not match the view controller's. view controller: <_TtGC7SwiftUI32NavigationStackHostingControllerVS_7AnyView_: 0x106014c00>; vc's navigationItem = <UINavigationItem: 0x105530320> title='Toolbar Repro' style=navigator searchController=0x106131200 SearchBarHidesWhenScrolling-default; vending navigation item <UINavigationItem: 0x106db4270> style=navigator searchController=0x106131200 SearchBarHidesWhenScrolling-explicit
Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want.
Try this:
(1) look at each constraint and try to figure out which you don't expect;
(2) find the code that added the unwanted constraint or constraints and fix it.
(
"<NSLayoutConstraint:0x600002171450 _TtC5UIKitP33_DDE14AA6B49FCAFC5A54255A118E1D8713ButtonWrapper:0x106a31fe0.width == _UIButtonBarButton:0x106dc4010.width (active)>",
"<NSLayoutConstraint:0x6000021558b0 'IB_Leading_Leading' H:|-(8)-[_UIModernBarButton:0x106a38010] (active, names: '|':_UIButtonBarButton:0x106dc4010 )>",
"<NSLayoutConstraint:0x600002170eb0 'IB_Trailing_Trailing' H:[_UIModernBarButton:0x106a38010]-(8)-| (active, names: '|':_UIButtonBarButton:0x106dc4010 )>",
"<NSLayoutConstraint:0x60000210aa80 'UIView-Encapsulated-Layout-Width' _TtC5UIKitP33_DDE14AA6B49FCAFC5A54255A118E1D8713ButtonWrapper:0x106a31fe0.width == 0 (active)>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x600002170eb0 'IB_Trailing_Trailing' H:[_UIModernBarButton:0x106a38010]-(8)-| (active, names: '|':_UIButtonBarButton:0x106dc4010 )>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.
Failed to send CA Event for app launch measurements for ca_event_type: 0 event_name: com.apple.app_launch_measurement.FirstFramePresentationMetric
Failed to send CA Event for app launch measurements for ca_event_type: 1 event_name: com.apple.app_launch_measurement.ExtendedLaunchMetrics
Overview
I have the following view hierarchy that mixes SwiftUI and UIKit:
AccordionView
└─ VStack
├─ Text
├─ Button
└─ UIViewRepresentable
└─ UIStackView
├─ UILabel
└─ UILabel
When tapping the button, the UIViewRepresentable hides and shows its content. This all works as expected.
However, in certain circumstances the view's sizing is rendered with the correct size, but the text can often render incorrectly, despite the frame seemingly looking as though it has enough room to render the text.
More info
Below you can see the UILabel has the correct frame height (the light grey background and coloured borders) but the text is rendered as though it has infinite width along one line.
There's a few configurations of my view hierarchy that seem to have this effect.
I've added a playground to the bottom of this post of various configurations to show what does and doesn't work, just copy and paste to see for yourself...
It seems of the ones that don't work, there's a couple of reasons why that may be:
HostedView and TextViewContainer do not do the following (I think we only need to do one of these things for auto layout/stack views to work effectively):
a) implement an intrinsic content size
b) return a 'good' size for systemLayoutSizeFitting().
UIHostingController shouldn't use intrinsic size (although I'm sure it should)
Something related to setting setContentCompressionResistancePriority() or setContentHuggingPriority() but having played about with this it doesn't seem relevant here...
I've played around with everything I can think of here but can't find a solution that works for all, although I'm 99% sure it's one or all of the points above.
If there are any UIKit gurus out there that can help that would be great! Ive already spent so much time on this 🫨
Playground
Swift Playground
Since iOS 26, navigationController?.toolbar no longer appears in the view hierarchy, and UIToolbar itself is not visible in the view tree.
Is there currently any supported way to access the toolbar’s container view or its underlying view hierarchy?
However, the API itself is not deprecated.
https://developer.apple.com/documentation/uikit/uinavigationcontroller/toolbar
Hello. I have an 12 year old app that still has some objective-c code in it. I have a place where i have a flip animation between 2 view controllers that looks like this:
[UIView transitionFromView:origView
toView:newViewController.view
duration:0.5
options:UIViewAnimationOptionTransitionFlipFromRight
completion:nil];
It has looked like this since 2012 at least.
In our production release, it works prior to 26.1, but in 26.1 and 26.2, the flip is off-center and looks weird. it's like both edges flip the same way. It's a little bit hard to explain.
If seen at least 2 other app store apps that i have installed behave this way too, from 26.1 and onwards.
Anyone else seen this? Is there anything that can be done about it?
Thankful for thoughts.
Platform
UIKit
iOS
UIActivityViewController
Environment
Device (issue reported): iPhone 16
iOS Version: 26.2
App Type: UIKit / Swift (standard modal presentation of UIActivityViewController)
Summary
When presenting UIActivityViewController to share a CSV file, the share sheet does not allow vertical scrolling, making lower actions (including Save to Files) unreachable.
The same flow works correctly when sharing a PDF, and the issue cannot be reproduced on other test devices.
Steps to Reproduce
Launch the app and log in
Navigate to More → Reports
Tap Export Report
Choose Export Report (CSV)
Observe the share sheet
Expected Result
The user should be able to vertically scroll the share sheet
All share actions (including Save to Files) should be reachable
Actual Result
Share sheet opens but vertical scrolling is disabled
Lower options (including Save to Files) are not reachable
No crash or console errors
I run into a layout problem where I cannot center an image inside ScrollView which is also inside Navigation Controller. The problem is surely the fact that there is a navigation bar because using this view without NavigationContoller works fine and the image is centered but I don’t know how to account for the space that navigation bar takes up.
Here is the code:
import UIKit
class PhotoViewController: UIViewController {
var photoName: String
private lazy var photoView = {
let image = UIImageView()
image.translatesAutoresizingMaskIntoConstraints = false
image.contentMode = .scaleAspectFit
image.clipsToBounds = true
return image
}()
var photoViewBottomConstraint: NSLayoutConstraint?
var photoViewLeadingConstraint: NSLayoutConstraint?
var photoViewTopConstraint: NSLayoutConstraint?
var photoViewTrailingConstraint: NSLayoutConstraint?
private lazy var scrollView = {
let sv = UIScrollView()
sv.translatesAutoresizingMaskIntoConstraints = false
return sv
}()
override func viewDidLoad() {
super.viewDidLoad()
setupUI()
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
updateMinZoomScaleForSize(view.bounds.size)
}
func updateMinZoomScaleForSize(_ size: CGSize) {
let widthScale = size.width / photoView.bounds.width
let heightScale = size.height / photoView.bounds.height
let minScale = min(widthScale, heightScale)
scrollView.minimumZoomScale = minScale
scrollView.zoomScale = minScale
}
func setupUI() {
photoView.image = UIImage(named: photoName)
scrollView.delegate = self
view.addSubview(scrollView)
scrollView.addSubview(photoView)
setupConstraints()
}
func setupConstraints() {
NSLayoutConstraint.activate([
scrollView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
scrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
scrollView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),
scrollView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor)
])
photoViewLeadingConstraint = NSLayoutConstraint(
item: photoView,
attribute: .leading,
relatedBy: .equal,
toItem: scrollView,
attribute: .leading,
multiplier: 1,
constant: 0
)
photoViewTopConstraint = NSLayoutConstraint(
item: photoView,
attribute: .top,
relatedBy: .equal,
toItem: scrollView,
attribute: .top,
multiplier: 1,
constant: 0
)
photoViewTrailingConstraint = NSLayoutConstraint(
item: photoView,
attribute: .trailing,
relatedBy: .equal,
toItem: scrollView,
attribute: .trailing,
multiplier: 1,
constant: 0
)
photoViewBottomConstraint = NSLayoutConstraint(
item: photoView,
attribute: .bottom,
relatedBy: .equal,
toItem: scrollView,
attribute: .bottom,
multiplier: 1,
constant: 0
)
photoViewLeadingConstraint?.isActive = true
photoViewTopConstraint?.isActive = true
photoViewTrailingConstraint?.isActive = true
photoViewBottomConstraint?.isActive = true
}
init(photoName: String) {
self.photoName = photoName
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
extension PhotoViewController: UIScrollViewDelegate {
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
photoView
}
func scrollViewDidZoom(_ scrollView: UIScrollView) {
updateConstraintsForSize(view.bounds.size)
}
func updateConstraintsForSize(_ size: CGSize) {
let yOffset = max(0, (size.height - photoView.frame.height) / 2)
photoViewTopConstraint?.constant = yOffset
photoViewBottomConstraint?.constant = yOffset
let xOffset = max(0, (size.width - photoView.frame.width) / 2)
photoViewLeadingConstraint?.constant = xOffset
photoViewTrailingConstraint?.constant = xOffset
view.layoutIfNeeded()
}
}
Hello,
We are seeing an intermittent crash when initializing a base UITableView with Apple's [initWithFrame:style:] initializer.
Crash stack:
Role: Foreground
OS Version: iOS 26.1
Exception Type: EXC_BREAKPOINT
Exception Subtype: KERN_INVALID_ADDRESS
EXC_BREAKPOINT:
0 libswiftCore.dylib +0x1358c0 _assertionFailure(_:_:file:line:flags:)
1 UIKitCore +0x1fdca0 0x188c26ca0 (0x188c26b20 + 384)
2 UIKitCore +0x1ffa60 0x188c28a60 (0x188c2890c + 340)
3 UIKitCore +0x2012d0 0x188c2a2d0 (0x188c2a1ec + 228)
4 UIKitCore +0x200f20 0x188c29f20 (0x188c29cac + 628)
5 UIKitCore +0x200428 0x188c29428 (0x188c29384 + 164)
6 UIKitCore +0x18af7f4 -[UITableMetricsAdapter _updateSharedSectionMetricsForListGeometry:]
7 UIKitCore +0x201da8 -[UITableMetricsAdapter tableBackgroundColor]
8 UIKitCore +0x1643a44 ___39-[UITableView _applyAppearanceDefaults]_block_invoke
9 UIKitCore +0x196f3d0 +[UIView _performSystemAppearanceModifications:]
10 UIKitCore +0x1643978 -[UITableView _applyAppearanceDefaults]
11 UIKitCore +0x202854 -[UITableView _setupTableViewCommon]
12 UIKitCore +0x1643760 -[UITableView initWithFrame:style:]
13 Application +0x30b6a40 closure #1 in variable initialization expression of MyAppClass.tableView
14 Application +0x30b6ef0 MyAppClass.init(frame:)
Has anyone else seen something like this?
Any insights or advice is much appreciated, thank you!
I am building an app for iOS and MacCatalyst that indexes files by storing their local paths. Because the app relies on the file remaining at its original location, I only want to accept items that can be opened in place.
I am struggling to determine if an item is "Open In Place" compatible early in the drag-and-drop lifecycle. Specifically:
In dropInteraction(_:canHandle:) and dropInteraction(_:sessionDidUpdate:), calling itemProvider.registeredTypeIdentifiers(fileOptions: [.openInPlace]) returns an empty array.
Only once the drop is actually committed in dropInteraction(_:performDrop:) does that same call return the expected type identifiers.
This creates a poor user experience. I want to validate the "In Place" capability at the very start of the session so the drop target only activates for valid files. If an item is ephemeral (like a dragged photo from the Photos app or a temporary export), the drop zone should not react at all.
How can I reliably detect if an NSItemProvider supports .openInPlace before the performDrop delegate method is called?
Topic:
App & System Services
SubTopic:
General
Tags:
Mac Catalyst
UIKit
Files and Storage
Foundation
Hi all,
I’m seeing a lifecycle behavior change on iOS 26.0 (and up).
While my app is in the foreground and active, pressing the hardware Lock button triggers didBecomeActive callbacks/notifications even though the app is transitioning away from active state.
I’m observing this sequence:
willResignActive
didBecomeActive
willResignActive
didEnterBackground
This happens for:
• UISceneDelegate.sceneDidBecomeActive(:)
• UIApplicationDelegate.applicationDidBecomeActive(:)
• UIApplication.didBecomeActiveNotification
On iOS 18 (same app, same code) I do not see didBecomeActive in the middle of locking/backgrounding.
Problem is reproduced on totally new project.
I would expect a normal transition to background:
• willResignActive → didEnterBackground
…and no extra didBecomeActive between them.
I have “became active” logic (refresh UI/state, resume timers, analytics). On iOS 26.0 this logic runs unexpectedly during locking, causing unnecessary work and incorrect state transitions.
Is this callback ordering expected on iOS 26.0 when pressing the Lock button?
If expected, what’s the recommended way to detect a “real” activation (and avoid transient didBecomeActive during locking/backgrounding)?
If this is a regression, is there a known workaround or best practice?
What works
let backButton = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
backButton.hidesSharedBackground = true
self.navigationItem.rightBarButtonItem = backButton
// or
self.navigationItem.leftBarButtonItem = backButton
What doesn't work
let backButton = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
backButton.hidesSharedBackground = true
self.navigationItem.backBarButtonItem = backButton
I've tried setting this property on all possible permutations and combinations e.g. Inside navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) and pushViewController(_ viewController: UIViewController, animated: Bool) of a custom UINavigationController to make sure.
Expected vs Actual behavior
Setting hidesSharedBackground = true should remove the glass background from both regular bar button items and back bar button items but it has no effect on backBarButtonItem.
Additional context
I’m aware of the UIDesignRequiresCompatibility Info.plist key, but I’m looking for a programmatic solution if there is one. The goal is to remove the glass background from back buttons.