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.

All subtopics
Posts under UI Frameworks topic

Post

Replies

Boosts

Views

Activity

ContactAccessPicker crashing issue
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) } }
1
2
484
Feb ’25
NSScrollPocket overlay appearing on scroll views in NSSplitViewController on macOS Tahoe
I have an NSSplitViewController with three columns: sidebar full-height content view with NSScrollView/NSTableView detail view. There's no (visible) titlebar and no toolbar. This layout has worked fine for years, but in Tahoe an unwanted overlay (~30-50px high) appears at the top of any column containing a scroll view with table content. Xcode suggests it's an NSScrollPocket. My research suggests it... Only affects columns with NSScrollView Plain NSView columns are unaffected Overlay height varies (~50px or ~30px depending on how I mess with title / toolbar settings) Disabling titlebar/toolbar settings reduces but doesn't eliminate the overlay The overlay obscures content and there doesn't appear to be any API to control its visibility. Is this intended behavior, and if so, is there a way to disable it for applications that don't need this UI element? If it helps visualise the desired result, the app is https://indigostack.app Any guidance would be appreciated!
Topic: UI Frameworks SubTopic: AppKit
5
2
378
Sep ’25
Occasional Keyboard Cannot Hide in iOS16.5
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?
Topic: UI Frameworks SubTopic: UIKit Tags:
1
2
333
May ’25
Custom Background Image Fails to Display on UIToolbar
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.
0
2
240
Sep ’25
EditMode & EditButton not working in a way I expect
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.
8
2
2.4k
May ’25
UIViewRepresentable never dismantled on deletion (MEMORY LEAK)
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)             }         }     } }
1
2
1.5k
May ’25
UITextView crash on iOS 18.4 beta
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 }];
Topic: UI Frameworks SubTopic: UIKit Tags:
9
2
2.1k
May ’25
Code coverage. SwiftUI Wrong Executable Lines
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.
1
2
828
Sep ’25
Show main window of SwiftUI app on macOS Sequoia after auto start
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
7
2
796
Apr ’25
iOS 26 @FocusState Doesn't Work If TextField Is In Toolbar
When I add a TextField with @FocusState to a toolbar, I noticed that setting focus = false doesn't cause the form to lose focus If I move the TextField out of the toolbar setting focus = false works fine. How can I unfocus the text field when the cancel button is tapped? Minimal example tested on Xcode Version 26.0 beta 6 (17A5305f): import SwiftUI struct ContentView: View { @State private var text: String = "" @FocusState private var focus: Bool var body: some View { NavigationStack { List { Text("Test List") } .toolbar { ToolbarItem(placement: .bottomBar) { TextField("Test", text: $text) .padding(.horizontal) .focused($focus) } ToolbarItem(placement: .bottomBar) { Button(role: .cancel) { focus = false // THIS DOESN'T WORK! } } } } } } #Preview { ContentView() }```
1
2
262
Sep ’25
ScrollView paging position is off in iOS 26
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 } } } }
0
2
211
Sep ’25
SwiftUI ColorPicker causes layout glitch when used from a sheet with detents
Given a sheet with [.medium] detents, that contains a native ColorPicker in SwiftUI: struct SheetView: View { @State var color: Color = .white var body: some View { ColorPicker( "Color", selection: $color, supportsOpacity: false ) .padding() } } struct ContentView: View { @State var isSheetOpen = false var body: some View { Button("Open Sheet") { isSheetOpen = true } .sheet(isPresented: $isSheetOpen) { SheetView() .presentationDetents([.medium]) } } } When I tap the ColorPicker's color indicator button, it presents the color picker sheet with a layout glitch. During the color picker presentation animation, the original sheet (SheetView) is rapidly pushed up and back down. It is a wild guess but I think it has to do something with keyboard avoidance. Unfortunately, this makes it impossible to use the picker in my app....
3
2
201
Feb ’25
ios26 NumberPad keyboard issue on iPad
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
4
1
374
Sep ’25
Accessing an actor's isolated state from within a SwiftUI view
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?
3
2
9.7k
Apr ’25
NSInvalidArgumentException Crash During Keyboard Language Switch on iOS 26
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!
Topic: UI Frameworks SubTopic: UIKit Tags:
2
2
118
Sep ’25
Allow custom tap gesture in List but maintain default selection gesture
I'm trying to create a List that allows multiple selection. Each row can be edited but the issue is that since there's a tap gesture on the Text element, the list is unable to select the item. Here's some code: import SwiftUI struct Person: Identifiable { let id: UUID let name: String init(_ name: String) { self.id = UUID() self.name = name } } struct ContentView: View { @State private var persons = [Person("Peter"), Person("Jack"), Person("Sophia"), Person("Helen")] @State private var selectedPersons = Set<Person.ID>() var body: some View { VStack { List(selection: $selectedPersons) { ForEach(persons) { person in PersonView(person: person, selection: $selectedPersons) { newValue in // ... } } } } .padding() } } struct PersonView: View { var person: Person @Binding var selection: Set<Person.ID> var onCommit: (String) -> Void = { newValue in } @State private var isEditing = false @State private var newValue = "" @FocusState private var isInputActive: Bool var body: some View { if isEditing { TextField("", text: $newValue, onCommit: { onCommit(newValue) isEditing = false }) .focused($isInputActive) .labelsHidden() } else { Text(person.name) .onTapGesture { if selection.contains(person.id), selection.count == 1 { newValue = person.name isEditing = true isInputActive = true } } } } } Right now, you need to tap on the row anywhere but on the text to select it. Then, if you tap on the text it'll go in edit mode. Is there a way to let the list do its selection? I tried wrapping the tap gesture in simultaneousGesture but that didn't work. Thanks!
3
2
1.9k
Feb ’25
Can’t focus the sidebar on tvOS when TabView contains TabSection elements
In a TabView with the .sidebarAdaptable style, including TabSection elements prevents the default back swipe on the remote from revealing the sidebar. Removing all TabSection elements and using only Tab elements makes it work as expected: import SwiftUI struct ContentView: View { var body: some View { TabView { Tab("Tab", systemImage: "square.fill") { Button(action: {}) { Text("Button") } } Tab("Tab", systemImage: "square.fill") { Button(action: {}) { Text("Button") } } Tab("Tab", systemImage: "square.fill") { Button(action: {}) { Text("Button") } } Tab("Tab", systemImage: "square.fill") { Button(action: {}) { Text("Button") } } Tab("Tab", systemImage: "square.fill") { Button(action: {}) { Text("Button") } } Tab("Tab", systemImage: "square.fill") { Button(action: {}) { Text("Button") } } Tab("Tab", systemImage: "square.fill") { Button(action: {}) { Text("Button") } } Tab("Tab", systemImage: "square.fill") { Button(action: {}) { Text("Button") } } Tab("Tab", systemImage: "square.fill") { Button(action: {}) { Text("Button") } } TabSection("Section") { Tab("Tab", systemImage: "square.fill") { Button(action: {}) { Text("Button") } } Tab("Tab", systemImage: "square.fill") { Button(action: {}) { Text("Button") } } } }.tabViewStyle(.sidebarAdaptable) } } Am I using it wrong, or is this a bug?
3
2
814
Jan ’25