We are trying to write an iOS app that supports regular and constrained widths using a TabView with .tabViewStyle(.sidebarAdaptable). On the surface this seems like a great way to write an app that supports all the different widths that your app may run in. Especially since Stage Manager and Apple Vision have made it easy for users to resize your apps window while it is running.
We are facing many challenges though. I will give a brief one liner of each below, but to truly experience them you need to run the sample app, or watch the sample videos included.
Issues
Basic TabView Issues
Double Navigation Bar: When tabs are collapsed into a "More" tab, there's an unwanted double navigation bar
Selection Sync: Tab selection gets out of sync when switching between narrow/wide layouts through the "More" tab
TabView Crash
Fatal crash occurs when resizing window to narrow width while Tab 5 is selected
Error: SwiftUI/SidebarAdaptableTabViewStyle_iOS.swift:482: Fatal error: Tried to update with invalid selection value
Section Handling Issues
Section Display Bug: Bottom tabs incorrectly show section names instead of tab names in narrow width
Tab Selection Mismatch: Tab identifiers don't match selected tabs in narrow width mode
Customization Issues
Inconsistent "Edit" button behavior in More tab
Unable to properly disable tab customization
Sample app and video
https://github.com/copia-wealth-studios/swiftui-tabview-sample
Explore the various UI frameworks available for building app interfaces. Discuss the use cases for different frameworks, share best practices, and get help with specific framework-related questions.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I am encountering a critical issue where a custom background image on a UIToolbar fails to display when the app is built with Xcode 26 and run on iOS 26 beta. The exact same implementation works perfectly on iOS 18 and earlier versions.
We first attempted to use the legacy setBackgroundImage method, which fails to render the image on iOS 26:
// 1. Get Navigation Bar and set basic properties
UINavigationBar* navBar = self.navigationBar;
navBar.hidden = NO;
navBar.translucent = NO;
// 2. Setup the UIToolbar instance
UIToolbar *toolBar = [[UIToolbar alloc] initWithFrame:navBar.bounds];
toolBar.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
// 3. Set the resizable image (This image does not appear on iOS 26)
UIImage* imagePortrait = [UIImage imageNamed:@"nav_bg"];
UIEdgeInsets insets = UIEdgeInsetsMake(0.f, 6.f, 0.f, 6.f);
[toolBar setBackgroundImage:[imagePortrait resizableImageWithCapInsets:insets]
forToolbarPosition:UIToolbarPositionAny
barMetrics:UIBarMetricsDefault];
We then migrated to the recommended modern UIToolbarAppearance to solve this, but the issue persists:
// 1. Prepare Image
UIImage* imagePortrait = [UIImage imageNamed:@"nav_bg"];
// Insets are applied via resizableImageWithCapInsets: (not shown in this snippet but implied)
// 2. Configure UIToolbarAppearance
UIToolbarAppearance *appearance = [[UIToolbarAppearance alloc] init];
appearance.backgroundImage = imagePortrait; // The image is correctly loaded (not nil)
// 3. Apply the Appearance
toolBar.standardAppearance = appearance;
// We also applied to scrollEdgeAppearance and compactAppearance.
Any information or recommended workarounds for displaying a custom background image on UIToolbar in the latest iOS 26 would be highly appreciated.
I have a TabView (no modifiers) as the top-level view in my app. Starting with iOS 26 it starts off partially "under" the Status Bar, and then repositions if I switch between apps.
Starting Point
After Switching To/From Another App
In the simulator, pressing "Home" and then reopening the app will fix it.
Anyone else seeing something similar? Is there a modifier I'm missing on TabView that might prevent this behaviour?
Thanks!
When disabling the opacity slider of color panels, my app crashes with unsatisfiable layout constraints. Feel free reproduce with a minimal test project: A macOS app based on the Xcode 26.0 template with only one line added to the ViewController's viewDidLoad() function:
NSColorPanel.shared.showsAlpha = false
The issue doesn't occur if this property is set to "true" or not set at all.
I just filed a corresponding bug report (FB20269686), although I don't expect any feedback from Apple ... as numerous issues I reported were never updated or commented at all (after migrating from RADARs).
Topic:
UI Frameworks
SubTopic:
AppKit
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
Hi community:
I noticed that each closure is counted as lines in code coverage (unit tests) (Xcode 14.1.0) in a swiftUI File. I mean, If you coded and VStack that involves another HStack, and HStack contains 4 lines, and the VStack contains 6 lines counting the HStack. The total executable lines should be 6 (6 lines in the file). But Xcode count 10, counting twice the HStack lines.
Is it a bug, or is it correct? You know, I don't know if Apple has another concept about executable lines.
Also, Is it possible to remove previews with any configuration from code coverage or constant files?
Thanks for all.
I have find out that a UIViewRepresentable, even with a simples UIView, seems to never be dismantled when deleted from a ForEach and this can cause serious crashes.
In the following example you can observe this behavior by deleting a row from the list. The dismantleUIView function of SomeUIViewRepresentable or the deinit of SomeUIView are never called.
Has anyone faced this and found a solution for it?
I have also filled a Feedback: FB11979117
class SomeUIView: UIView {
deinit {
print(#function)
}
}
struct SomeUIViewRepresentable: UIViewRepresentable {
func makeUIView(context: Context) -> SomeUIView {
let uiView = SomeUIView()
uiView.backgroundColor = .systemBlue
return uiView
}
func updateUIView(_ uiView: SomeUIView, context: Context) { }
static func dismantleUIView(_ uiView: SomeUIView, coordinator: Coordinator) {
print(#function)
}
}
struct Model: Identifiable {
let id = UUID()
}
struct ContentView: View {
@State var models = [Model(), Model(), Model(), Model(), Model()]
var body: some View {
List {
ForEach(models) { _ in
SomeUIViewRepresentable()
}
.onDelete {
models.remove(atOffsets: $0)
}
}
}
}
Hi everyone,
I have the following issue that I have tried to tweak every possible modifier of ScrollView and still got the same result in iOS 26.
Description:
Create a SwiftUI ScrollView with scrollTargetBehavior of paging, also create a bottom UI view below the ScrollView.
If the starting index is not 0, the position of current page will be off with part of previous page shown above it.
It only happens on iOS 26, not on iOS 18.
Also if bottom UI view (text view in this case) is removed, it also works fine.
I want to see if there is a solution for it or it's an iOS 26 bug. Thanks!
import SwiftUI
struct ContentView: View {
@State private var currentPageIndex: Int? = 3
var body: some View {
VStack {
scrollView
Text("Bottom Bar")
.frame(maxWidth: .infinity)
.frame(height: 80)
.background(.red)
}
.background(.black)
}
@ViewBuilder
var scrollView: some View {
VerticalPagerView(
currentPageIndex: $currentPageIndex,
itemCount: 10,
content: Array(0...9).map { index in
content(for: index)
}
)
}
@ViewBuilder
private func content(for index: Int) -> some View {
// Empty view with random background color
Color(
red: Double((index * 25 + 0) % 255) / 255.0,
green: Double((index * 25 + 80) % 255) / 255.0,
blue: Double((index * 25 + 160) % 255) / 255.0
)
}
}
struct VerticalPagerView<Content: View>: View {
@Binding private var currentPageIndex: Int?
private let itemCount: Int
private let content: [Content]
init(
currentPageIndex: Binding<Int?>,
itemCount: Int,
content: [Content]
) {
self._currentPageIndex = currentPageIndex
self.itemCount = itemCount
self.content = content
}
var body: some View {
GeometryReader { geometryReader in
ScrollViewReader { reader in
ScrollView(.vertical) {
LazyVStack(spacing: 0) {
ForEach(0 ..< itemCount, id: \.self) { index in
content[index]
.id(index)
.containerRelativeFrame(.vertical, alignment: .center)
.clipped()
}
}
.frame(minHeight: geometryReader.size.height)
.scrollTargetLayout()
}
.scrollIndicators(.hidden)
.onAppear {
guard let currentPageIndex = currentPageIndex else { return }
reader.scrollTo(currentPageIndex, anchor: .center)
}
}
.scrollPosition(id: $currentPageIndex, anchor: .center)
.ignoresSafeArea()
.scrollTargetBehavior(.paging)
.onChange(of: currentPageIndex) { oldIndex, newIndex in
}
}
}
}
I have something that looks like:
NavigationStack {
List(self.items, id: \.self, selection: self.$selectedItems) { item in
NavigationLink {
ItemView(item: item)
.environment(\.managedObjectContext, self.viewContext)
} label: {
LabelWithMenuView(object: item) { ptr in
self.labelHandler(item: item, newName: ptr)
}
}
}
if self.editMode?.wrappedValue == .active {
editButtons
} else {
TextField("Add Item", text: self.$newItem)
.onSubmit {
self.addItem()
self.newItem = ""
}
.padding()
}
}
#if os(iOS)
.toolbar {
EditButton()
}
.onChange(of: self.editMode?.wrappedValue) { old, new in
print("editMode \(old) -> \(new)")
}
#endif
With that layout, the edit button doesn't show up at all; if I put it as part of the List, it does show up, but the first click doesn't do anything; after that, it works, but the onChange handler doesn't show it getting changed, and the editButtons don't go away.
Some character display on iOS 26 cause crash
String sample
Crash stack
UITextView crash when setting attributed text that contains substring ffi and attributedText contains NSFontAttributeName, NSForegroundColorAttributeName
Reproducible case:
UITextView *textView = [[UITextView alloc] init];
textView.attributedText = [[NSAttributedString alloc] initWithString:@"ffi" attributes:@{
NSParagraphStyleAttributeName: [self createParagraphOfLineHeight:20],
NSFontAttributeName: [UIFont systemFontOfSize:fontSize weight:UIFontWeightRegular],
NSForegroundColorAttributeName: UIColor.black
}];
Help,I have encountered a thorny problem! In systems with iOS 16.5 and above, there is a probability that the keyboard will not disappear after it appears. And once it appears, unless the app is restarted, all places where the keyboard is used cannot be closed.
I have tried using the forced shutdown method [UIView endEditing:YES], but it didn't work. When this exception occurs, I notice that there will be two UITextEffectsWindow at the same time.
Does anyone know how to solve it?
On an iPad running iOS26, there is an issue with the numberPad keyboard
I have a UITextField with a keyboard type of .numberPad
When I first tap in the field, a new number pad with just numbers (similar to the one that shows up on iPhone) shows up.
When I tap again in the field, that number pad goes away.
When I tap in the field again, the full keyboard with numbers etc shows up (this is the one that used to always show up pre-iOS26)
Topic:
UI Frameworks
SubTopic:
UIKit
Hello,
I have been receiving crash reports on iOS 26 related to a view containing a UITextField. Although I have not been able to reproduce the issue locally and the exact reproduction steps are unknown, the call stack suggests the crash may be related to language or input method changes.
If anyone has encountered a similar crash on iOS 26 or has any insights regarding language/input-related issues impacting UITextField behavior, your help would be greatly appreciated. The call stack from the reports is attached below.
Exception
NSInvalidArgumentException
-[__NSPlaceholderArray initWithObjects:count:]
attempt to insert nil object from objects[1]
Fatal Exception: NSInvalidArgumentException
0 CoreFoundation 0xc98c8 __exceptionPreprocess
1 libobjc.A.dylib 0x317c4 objc_exception_throw
2 CoreFoundation 0xe1d7c -[__NSPlaceholderArray initWithObjects:count:]
3 CoreFoundation 0x1485d0 +[NSArray arrayWithObjects:count:]
4 UIKitCore 0xfc4d44 -[UIInlineInputSwitcher updateInputModes:withHUD:]
5 UIKitCore 0xfc4fe0 -[UIIndicatorInputSwitcher switchMode:withHUD:withDelay:]
6 UIKitCore 0xfc31d4 -[UIInputSwitcher showsLanguageIndicator:]
7 UIKitCore 0xa16dc8 __140-[_UIKeyboardStateManager _setupDelegate:delegateSame:hardwareKeyboardStateChanged:endingInputSessionIdentifier:force:delayEndInputSession:]_block_invoke_4
8 libdispatch.dylib 0x1abc _dispatch_call_block_and_release
9 libdispatch.dylib 0x1b7cc _dispatch_client_callout
10 libdispatch.dylib 0x38af0 _dispatch_main_queue_drain.cold.5
11 libdispatch.dylib 0x10ea8 _dispatch_main_queue_drain
12 libdispatch.dylib 0x10de4 _dispatch_main_queue_callback_4CF
13 CoreFoundation 0x6b520 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__
14 CoreFoundation 0x1dd14 __CFRunLoopRun
15 CoreFoundation 0x1cc44 _CFRunLoopRunSpecificWithOptions
16 GraphicsServices 0x1498 GSEventRunModal
17 UIKitCore 0xaa6d8 -[UIApplication _run]
18 UIKitCore 0x4ec24 UIApplicationMain
Thank you!
It seems like it is no longer possible to open the main window of an app after the app has been launched by the system if the "Auto Start" functionality has been enabled.
I am using SMAppService.mainApp to enable to auto start of my app. It is shown in the macOS system settings and the app is automatically started - but the main window is not visible.
How can I change this behaviour so the main window of the app is always visible when started automatically?
I have not noticed this behaviour before the release of macOS Sequoia. My app is using Swift 6 and the latest version of macOS and Xcode.
Regards
Topic:
UI Frameworks
SubTopic:
SwiftUI
Is there a way to access an Icon Composer .icon file in Swift or Objective-C? Any way to get this in an NSImage object that I can display in an image view? Thanks.
I'm trying to understand a design pattern for accessing the isolated state held in an actor type from within a SwiftUI view.
Take this naive code:
actor Model: ObservableObject {
@Published var num: Int = 0
func updateNumber(_ newNum: Int) {
self.num = newNum
}
}
struct ContentView: View {
@StateObject var model = Model()
var body: some View {
Text("\(model.num)") // <-- Compiler error: Actor-isolated property 'num' can not be referenced from the main actor
Button("Update number") {
Task.detached() {
await model.updateNumber(1)
}
}
}
}
Understandably I get the compiler error Actor-isolated property 'num' can not be referenced from the main actor when I try and access the isolated value. Yet I can't understand how to display this data in a view. I wonder if I need a ViewModel that observes the actor, and updates itself on the main thread, but get compile time error Actor-isolated property '$num' can not be referenced from a non-isolated context.
class ViewModel: ObservableObject {
let model: Model
@Published var num: Int
let cancellable: AnyCancellable
init() {
let model = Model()
self.model = model
self.num = 0
self.cancellable = model.$num // <-- compile time error `Actor-isolated property '$num' can not be referenced from a non-isolated context`
.receive(on: DispatchQueue.main)
.sink { self.num = $0 }
}
}
Secondly, imagine if this code did compile, then I would get another error when clicking the button that the interface is not being updated on the main thread...again I'm not sure how to effect this from within the actor?
Given Apple's new .limited contact authorization introduced in ios18, I want to be able to present the ContactAccessPicker directly from my app, via ionic capacitor. I present the .contactAccessPicker view via a UIHostingController, and I manage the view controller's dismissal accordingly when the ContactAccessPicker completes and is no longer presented.
Bug: After a few searches or interactions with the Contact Access Picker (ex. searching, selecting contacts, clicking the "show selected" button), the contact access picker crashes and the overlay remains. Any interaction with my app is then blocked because I can't detect that the contact access picker has disappeared when it crashes so I can't dismiss the viewController.
Is there a way for me to prevent the contact access picker from crashing, and how can I detect if it does crash, so I can at least dismiss the view controller if that happens?
struct ContactAccessPickerView: View {
@Binding var isPresented: Bool
let completion: @MainActor ([String]) -> Void
var body: some View {
Group {
if #available(iOS 18.0, *) {
Color.clear
.contactAccessPicker(isPresented: $isPresented) { result in
Task { @MainActor in
completion(result)
}
}
} else {
}
}
}
}
@objc func selectMoreContacts(_ call: CAPPluginCall) {
guard isContactsPermissionGranted() else {
call.resolve(["success": false])
return
}
// Save the call to ensure it's available until we finish
self.bridge?.saveCall(call)
DispatchQueue.main.async { [weak self] in
guard let self = self else { return }
var isPresented = true
let picker = ContactAccessPickerView(isPresented: .init(get: { isPresented }, set: { isPresented = $0 })) { contacts in
call.resolve(["success": true])
self.dismissAndCleanup(call)
}
let hostingController = UIHostingController(rootView: picker)
hostingController.modalPresentationStyle = .overFullScreen
self.bridge?.viewController?.present(hostingController, animated: true)
}
}
It appears that hidesBottomBarWhenPushed no longer works in iOS 26 Beta 1.
Is it supposed to work, is it going away or is there a alternate behavior we should be using?
Topic:
UI Frameworks
SubTopic:
UIKit
[Also submitted as FB20213961]
SwiftUI Button with a label: closure containing only an Image view has a smaller tap target than buttons created with a Label or the convenience initializer. The hit area shrinks to the image bounds instead of preserving the standard minimum tappable size.
SCREEN RECORDING
On a physical device, the difference is obvious—it’s easy to miss the button. Sometimes it even shows the button-tapped bounce animation but doesn’t trigger the action.
SYSTEM INFO
Xcode Version 26.0 (17A321)
macOS 15.6.1 (24G90)
iOS 26.0 (23A340)
SAMPLE CODE
The following snippet shows the difference in hit targets between the convenience initializer, a Label, and an Image (the latter two in a label: closure).
// ✅ Hit target is entire button
Button("Button 1", systemImage: "1.square.fill") {
print("Button 1 tapped")
}
// ✅ Hit target is entire button
Button {
print("Button 2 tapped")
} label: {
Label("Button 2", systemImage: "2.square.fill")
}
// ❌ Hit target is smaller than button
Button {
print("Button 3 tapped")
} label: {
Image(systemName: "3.square.fill")
}