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

SwiftUI animation is laggy in NSStatusItem since macOS 26 Tahoe
My app is a bit of a special case and relies on a custom view in a NSStatusItem. I use a NSHostingView and add it as a subview to my NSStatusItem's .button property. Since macOS 26 Tahoe, even simple animations like a .frame change of a Circle won't animate smoothly even though the same SwiftUI animates normally in a WindowGroup. class AppDelegate: NSObject, NSApplicationDelegate { private let statusItem: NSStatusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength) func applicationDidFinishLaunching(_ aNotification: Notification) { let subview = NSHostingView(rootView: AnimationView()) let view = self.statusItem.button view?.addSubview(subview) subview.translatesAutoresizingMaskIntoConstraints = false guard let view = view else { return } NSLayoutConstraint.activate([ subview.centerXAnchor.constraint(equalTo: view.centerXAnchor), subview.centerYAnchor.constraint(equalTo: view.centerYAnchor), subview.widthAnchor.constraint(equalToConstant: 22), subview.heightAnchor.constraint(equalToConstant: 22) ]) } } struct AnimationView: View { @State private var isTapped = false @State private var size: CGSize = .init(width: 4, height: 4) var body: some View { Circle() .fill(.pink) .frame(width: size.width, height: size.height) .frame(width: 20, height: 20) // .frame(maxHeight: .infinity) // .padding(.horizontal, 9) // .frame(height: 22) .contentShape(Rectangle()) // .background(Color.blue.opacity(0.5)) .onTapGesture { withAnimation(.interactiveSpring(response: 0.85, dampingFraction: 0.26, blendDuration: 0.45)) { // withAnimation(.spring()) { if isTapped { size = .init(width: 4, height: 4) } else { size = .init(width: 16, height: 16) } } isTapped.toggle() }} } Example project: https://app.box.com/s/q28upunrgkxyyd97ovslgud9yitqaxfk
1
0
327
2w
Tab bar animates from first tab to restored selection at launch with .tabBarMinimizeBehavior(.onScrollDown)
[Submitted as FB23998635] On iPhone, applying .tabBarMinimizeBehavior(.onScrollDown) to a SwiftUI TabView causes the native tab bar to briefly show the first declared tab before animating to the already-restored selection during app launch. The selected tab is persisted with @AppStorage and is already restored before the TabView is presented. The sample contains no explicit animations, transactions, navigation containers, loading states, asynchronous work, or post-launch selection changes. Removing .tabBarMinimizeBehavior(.onScrollDown) eliminates the launch animation entirely. Likewise, starting with .tabBarMinimizeBehavior(.never) and changing it to .onScrollDown after a one-second delay also eliminates the issue. The behavior reproduces with three simple tabs and a direct @AppStorage selection binding. ENVIRONMENT • iOS 26 & 27 REPRO STEPS Build and run the attached sample. Select the "Two" tab. Force-quit the app. Relaunch the app. Observe the tab bar during launch. ACTUAL The tab indicator initially appears on "One", the first declared tab, then animates to the correctly restored "Two" selection. EXPECTED The restored tab should be selected and stationary from the first visible frame, with no launch animation. SAMPLE CODE struct ContentView: View { private enum AppTab: String, Hashable { case one case two case three } @AppStorage("selectedGenericTab") private var selectedTab: AppTab = .three var body: some View { TabView(selection: $selectedTab) { Tab("One", systemImage: "1.circle", value: AppTab.one) { ReproTabContent(title: "One", color: .orange) } Tab("Two", systemImage: "2.circle", value: AppTab.two) { ReproTabContent(title: "Two", color: .blue) } Tab("Three", systemImage: "3.circle", value: AppTab.three) { ReproTabContent(title: "Three", color: .green) } } .tabBarMinimizeBehavior(.onScrollDown) } } private struct ReproTabContent: View { let title: String let color: Color var body: some View { ZStack { color.opacity(0.2) .ignoresSafeArea() Text(title) .font(.largeTitle) } } }
2
0
456
2w
UISearchController text field not receiving touches when another UISearchController is attached to navigationItem.searchController on iOS 26
On iOS 26, UISearchController becomes non-interactive when presenting a second UISearchController from another tab of a UITabBarController. let tabBar = UITabBarController() let first = FirstViewController() first.title = "First" let second = SecondViewController() second.title = "Second" let nav1 = UINavigationController(rootViewController: first) let nav2 = UINavigationController(rootViewController: second) nav1.tabBarItem = UITabBarItem( title: "First", image: nil, tag: 0 ) nav2.tabBarItem = UITabBarItem( title: "Second", image: nil, tag: 1 ) tabBar.viewControllers = [ nav1, nav2 ] The app has two tabs. Each tab has its own UINavigationController. Tab 1: A UISearchController is assigned to navigationItem.searchController. class FirstViewController: UIViewController { private let searchController = UISearchController( searchResultsController: nil ) override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .systemBackground searchController.obscuresBackgroundDuringPresentation = false searchController.searchResultsUpdater = self navigationItem.searchController = searchController navigationItem.hidesSearchBarWhenScrolling = false definesPresentationContext = true } } Tab 2: A button presents another UISearchController using present(_:animated:). class SecondViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .systemBackground let button = UIButton( type: .system ) button.setTitle( "Open Search", for: .normal ) button.addTarget( self, action: #selector(openSearch), for: .touchUpInside ) button.translatesAutoresizingMaskIntoConstraints = false view.addSubview(button) NSLayoutConstraint.activate([ button.centerXAnchor.constraint( equalTo: view.centerXAnchor ), button.centerYAnchor.constraint( equalTo: view.centerYAnchor ) ]) definesPresentationContext = true } @objc private func openSearch() { let searchController = UISearchController( searchResultsController: nil ) navigationController?.present( searchController, animated: true ) } } On iOS 17 and iOS 18 this works correctly. On iOS 26: The search controller appears. The Cancel button works. The search text field cannot receive touches and does not become first responder. If I remove: navigationItem.searchController = searchController from Tab 1, the search controller in Tab 2 works correctly. This looks like a UIKit regression introduced in iOS 26.
Topic: UI Frameworks SubTopic: UIKit Tags:
1
0
199
2w
popoverTips don't display for toolbar menu buttons in iOS 26.1
[Also submitted as FB20756013] A popoverTip does not display for toolbar menu buttons in iOS 26.1 (23B5073a). The same code displays tips correctly in iOS 18.6. The issue occurs both in the simulator and on a physical device. Repro Steps Build and run the Sample Code below on iOS 26.1. Observe that the popoverTip does not display. Repeat on iOS 18.6 to confirm expected behavior. Expected popoverTips should appear when attached to a toolbar menu button, as they do in iOS 18.6. Actual No tip is displayed on iOS 26.1. System Info macOS 15.7.1 (24G231) Xcode 26.1 beta 3 (17B5045g) iOS 26.1 (23B5073a) Screenshot Screenshot showing two simulators side by side—iOS 18.6 on the left (tip displayed) and iOS 26.1 on the right (no tip displayed). Sample code import SwiftUI import TipKit struct PopoverTip: Tip { var title: Text { Text("Menu Tip") } var message: Text? { Text("This tip displays on iOS 18.6, but NOT on iOS 26.1.") } } struct ContentView: View { var tip = PopoverTip() var body: some View { NavigationStack { Text("`popoverTip` doesn't display on iOS 26.1 but does in iOS 18.6") .padding() .toolbar { ToolbarItem(placement: .topBarTrailing) { Menu { Button("Dismiss", role: .cancel) { } Button("Do Nothing") { } } label: { Label("More", systemImage: "ellipsis") } .popoverTip(tip) } } .navigationTitle("Popover Tip Issue") .navigationBarTitleDisplayMode(.inline) } } }
6
3
938
2w
Unable to use AppIntents
Hi, I'm trying to add Shortcuts using AppIntents but unable to get past this error: 'AppShortcutsProvider' property 'appShortcuts' requires builder syntax This is the AppShortcutsProvider struct: import AppIntents struct MyAppShortcuts: AppShortcutsProvider { @AppShortcutsBuilder static var appShortcuts: [AppShortcut] { AppShortcut( intent: OpenDashboardIntent(), phrases: [ "Open dashboard in \(.applicationName)", "Show my \(.applicationName) dashboard" ], shortTitle: "Open Dashboard", systemImageName: "square.grid.2x2" ) } } And I have only one intent: import AppIntents struct OpenDashboardIntent: AppIntent { static var title: LocalizedStringResource = "Open Dashboard" static var openAppWhenRun: Bool = true @MainActor func perform() async throws -> some IntentResult & ProvidesDialog { return .result(dialog: "Opening dashboard") } } I searched the error online but the fixes were to use @AppShortcutsBuilder and skipping commas in case of registering multiple app intents - I'm already following all that. What am I missing? Thanks.
0
0
403
2w
Inspector Panel Visual UI
How can I get the inspector panel on the Mac to be respected by the toolbar? In Xcode and Pages, the inspector panel runs the entire length of the app so that everything slides over when it's invoked. But in my testing, the toolbar always overlaps the inspector. import SwiftUI @main struct MyApp: App { var body: some Scene { WindowGroup { ContentView() } } } struct ContentView: View { @State private var selectedItem: String? = "Page 1" @State private var inspectorVisible = true let items = ["Page 1", "Page 2", "Page 3"] var body: some View { NavigationSplitView { List(items, id: \.self, selection: $selectedItem) { item in Label(item, systemImage: "doc") } } detail: { Text(selectedItem ?? "Nothing selected") .font(.title2) .foregroundStyle(.secondary) .inspector(isPresented: $inspectorVisible) { List { Section("Properties") { LabeledContent("Width", value: "100") LabeledContent("Height", value: "200") } Section("Style") { LabeledContent("Color", value: "Blue") LabeledContent("Opacity", value: "100%") } } .scrollContentBackground(.hidden) } } .toolbar { ToolbarItemGroup(placement: .principal) { Button("Draw", systemImage: "pencil") {} Button("Shape", systemImage: "circle") {} Button("Text", systemImage: "textformat") {} } ToolbarItem () { Button("Share", systemImage: "square.and.arrow.up") {} } ToolbarItem() { Button("Inspector", systemImage: "sidebar.right") { inspectorVisible.toggle() } } } .navigationTitle("My Project") } } #Preview { ContentView() .frame(width: 1100, height: 600) }
Topic: UI Frameworks SubTopic: SwiftUI
0
0
282
2w
Distinguishing background from user app launches
When adopting the Scene Delegate, the applicationState changes from indicating app state to indicating scene state. I previously used this as a signal to determine whether my iOS app was launched in the background or launched by the user. Given the change, it seems like applicationState should no longer be used in that manner in the App Delegate. Would you recommend using UIApplication.shared.backgroundTimeRemaining to distinguish a background launch from a user launch? assuming this is a very large value for user launches. Are there corner cases that I may not expect?
1
0
535
3w
Can't Drag and Drop a file promise into /tmp
This happens with my own code as well as with the Apple example code here: Supporting Drag and Drop Through File Promises When dragging a file promise, the above example code will fail if the destination is in /tmp. It will print out the following message to the console: An error occurred while attempting to get a unique promise file URL. Error: Did not receive a valid URL. It doesn't seem to fail if you create a directory inside /tmp and drop into that. But dropping in /tmp fails 100% of the time. And it fails for MacOS Versions from Sequoia all the way up to the most recent Golden Gate beta. Using /tmp as a destination should most certainly be allowed, but if for some reason it isn't, is there any way in my own code to detect the drop destination and perhaps warn the user that they need to drop somewhere else? To reproduce this error, use the following steps: Download the Apple example code from the link above Open the project in Xcode, build it, and run it Drag any image into the example app's main window Open a Finder window and navigate to /tmp Drag the image from the example app into the /tmp directory in the Finder window. You will see the above error in the Xcode console and the drop will fail.
Topic: UI Frameworks SubTopic: AppKit
0
0
392
3w
iOS 27 – What changes are mandatory to support Liquid Glass?
We're preparing our SDK and host applications for iOS 27 and would like to understand the mandatory requirements for supporting the new Liquid Glass design. Beyond building with the iOS 27 SDK, are there any required implementation or migration steps (UIKit or SwiftUI) that developers must adopt to ensure full compatibility? Are there any behaviors or APIs that require explicit changes, or does the system automatically handle Liquid Glass for standard controls? We're specifically interested in the minimum required changes for compliance and compatibility, rather than optional design enhancements. Thanks in advance for any guidance.
Topic: UI Frameworks SubTopic: General
1
0
214
3w
What's the preferred way enable scroll behind tab bar in nested ScrollView in SwiftUI
I am having a root TabView with tabs. One of the tabs has a TabBar with page style as the root view and each Page has a ScrollView. Unfortunately the scroll view get's clipped by the parent TabView size. But I want to make the ScrollView content to go behind the root TabView's tab bar like it would work if I would have the ScrollView as direct child to the root TabBar I tried using ignoreSafeArea on the page style TabView and there are other weird bugs, it stops reacting to the Binding pageIndex I am having as a State. The custom page index view disappears Sample code: https://github.com/BProg/TabViewScrollViewBug.git
2
0
165
3w
SwiftUI's `scrollTo(id:anchor:)` doesn't work if the ScrollView is scrolling
Can somebody tell me if I'm doing something wrong or SwiftUI's scrollTo(id:anchor:) just doesn't work if the ScrollView is scrolling? I have a trivial example that demonstrates the issue: import SwiftUI @main struct MyApp: App { var body: some Scene { WindowGroup { ContentView() } } } struct Item: Identifiable { let id = UUID() let timestamp: Date let text: String } struct ContentView: View { @State private var items: [Item] = (0...10_000).map{ .init(timestamp: Date(), text: "Row \($0)") } @State private var scrollPosition = ScrollPosition(idType: Item.ID.self) @State private var newMessage: String = "" var body: some View { ScrollView { LazyVStack { ForEach(items) { item in ItemView(item: item) } }.scrollTargetLayout() } .defaultScrollAnchor(.bottom, for: .initialOffset) .scrollPosition($scrollPosition, anchor: .bottom) .safeAreaBar(edge: .bottom) { HStack { TextField("Type here", text: $newMessage, axis: .vertical) .textFieldStyle(.roundedBorder) Button("Send", action: { let trimmed = newMessage.trimmingCharacters(in: .whitespacesAndNewlines) guard !trimmed.isEmpty else { return } newMessage = "" items.append(.init(timestamp: .now, text: trimmed)) withAnimation(.smooth) { scrollPosition.scrollTo(id: items.last!.id, anchor: .bottom) } }) }.padding() } } } struct ItemView: View { let item: Item var body: some View { VStack(alignment: .leading) { Text(item.text) Text(item.timestamp.formatted()) }.padding() .frame(maxWidth: .infinity, alignment: .leading) .background(Color(red: .random(in: 0...1), green: .random(in: 0...1), blue: .random(in: 0...1))) } } #Preview { ContentView() }
2
0
226
3w
How to send a message from menu item in SwiftUI App to ContentView
I'm just not getting it. My app adds a custom Import menu item to the File menu. I want to have it tell the sole ContentView to run the fileImporter. Here's how I have it set up. Changing the showFileImporter variable to supposed to make stuff happen, but it doesn't change. @main struct Blah: App { @State public var contentView = ContentView(); var body:some Scene { WindowGroup { // ContentView() // It started out defining the content like normal, but I saw somewhere that if I declared it as a var up top, then I'd have an actual object that I could tell to do things, like calling the importTerms() method below. self.contentView } .commands { CommandGroup(after:.newItem) { Button("Import…") { contentView.importTerms(); } } } } struct ContentView: View { @State private var showFileImporter = false; var body: some View { VStack { ...stuff... } } .fileImporter(isPresented:$showFileImporter, allowedContentTypes:[.text], allowsMultipleSelection:false) { result in } public func importTerms() { print("\(showFileImporter)"); // ->false showFileImporter = true; print("\(showFileImporter)"); // ->yep, still false } } But it doesn't work. It calls importTerms(), and a breakpoint inside that method does get hit. But it doesn't change the value of showFileImporter and the fileImporter never appears. What kind of weird world has Swift made where setting a variable to true doesn't set it to true and there's no error at build or runtime?
Topic: UI Frameworks SubTopic: SwiftUI
15
1
362
3w
App hangs on navigation bar rendering cycle
We are currently having an issue with our app hanging for some (not all) of our iOS 26.x users. The hang lasts long enough for the system to kill the app after a while. As of now we are unable to reproduce the issue on our own test devices, yet users dealing with the issue can produce it consistently. Looking at the stack traces we managed to retrieve, the hangup seems to occur in the layout rendering cycle of the navigation bar in the UINavigationController. The hangup doesn't happen at the exact same stack trace every time. But it always seems to be in the rendering cycle. Stack trace 1 Stack trace 2 Stack trace 3 Since the issue not reproducable in our own test environment it's hard to properly debug. The only adjustments to the navigationbar/navigationitem in our code is setting the title and a few bar buttons: self.navigationItem.title = NSLocalizedString("main_list_title", comment: "") let cancelItem = UIBarButtonItem(barButtonSystemItem: .stop, target: self, action: #selector(cancelListSelection)) let addPostItem = UIBarButtonItem(image: UIImage(named: "AddButton"), style: .plain, target: self, action: #selector(addItemTapped)) let extraMenuItem = UIBarButtonItem(image: UIImage(named: "ExtraButton"), style: .plain, target: self, action: #selector(extraItemTapped)) self.navigationItem.setLeftBarButton(cancelItem, animated: true) self.navigationItem.setRightBarButtonItems([addPostItem, extraMenuItem], animated: true) let previousButton = UIBarButtonItem(image: UIImage(named: "LeftArrow"), style: .plain, target: self, action: #selector(openPrevious)) let nextButton = UIBarButtonItem(image: UIImage(named: "RightButton"), style: .plain, target: self, action: #selector(openNext)) self.setToolbarItems([previousButton, nextButton], animated: true) And for one or two controllers the title is replaced by a UISegmentControl: let segControl = UISegmentedControl(items: ["1", "2", "3"]); segControl.selectedSegmentIndex = 0 segControl.addTarget(self, action: #selector(segmentValueChanged), for: .valueChanged) self.navigationItem.titleView = segControl Is anyone familiar with hangs at these particular stack traces and their cause?
Topic: UI Frameworks SubTopic: UIKit Tags:
4
0
597
3w
SwiftUI `List` incorrectly reuses stale `Equatable` objects when redrawing
Hi, We have found a nasty issue with SwiftUI List and Equatable reference types. In such scenarios List might resurface stale objects from some internal cache when inserting new equal instances, which can lead to outdated cells on screen. Detailed information can be found in our bug report (FB23923342). Since List is quite a widespread component we thought dropping a few lines here in addition to our report could be helpful, especially if you have been bitten by this issue in the past.
0
0
162
3w
Adding top content inset to an NSScrollView below an NSSplitViewItemAccessoryViewController in a sidebar
I have a question about NSSplitViewItemAccessoryViewController, introduced with the new design since macOS 26, and how it interacts with NSScrollView content insets. My app has a typical three-pane window whose content view controller is an NSSplitViewController subclass. The sidebar contains a tab view with a segmented control, similar to Xcode, for switching between different sidebar panes. Each pane contains an NSScrollView whose content can be scrolled. Before macOS 26, I placed the segmented control directly inside the sidebar view. To adopt the new scroll-edge effect and allow the sidebar content to extend visually into the window title bar, I moved the segmented control into an NSSplitViewItemAccessoryViewController. However, with this layout, the scroll view starts immediately below the segmented control, which feels visually cramped. I'd like to add a few points of top inset before the document view begins. Previously, I achieved this by setting: scrollView.additionalSafeAreaInsets.top However, this now causes the accessory view's scroll-edge effect to extend into the additional safe-area inset, producing an awkward blurred region underneath the segmented control. Ideally, I'd like the scroll view to begin directly below the segmented control while still having a small inset before the document content, with the scroll-edge effect ending exactly at the bottom of the accessory view. In addition to additionalSafeAreaInsets, I tried the following approaches, but neither produced the desired result: Set scrollView.automaticallyAdjustsContentInsets to false and specify scrollView.contentInsets.top. This disables the automatic safe-area adjustment, causing the entire scroll view to move upward underneath the accessory view. Set scrollView.contentView.automaticallyAdjustsContentInsets to false and specify scrollView.contentView..contentInsets.top. This produces the same result as above. Set the accessory view's preferredScrollEdgeEffectStyle to .soft. The segmented control becomes too transparent, making its unselected labels difficult to read. Xcode's sidebar appears to achieve the behavior I'm looking for. What is the recommended way to implement this layout on macOS 26 and 27? Xcode's sidebar (macOS 26) My app's sidebar (macOS 26, work in develop) with additionalSafeAreaInsets
Topic: UI Frameworks SubTopic: AppKit
0
0
184
3w
Timing issue with updating two state variables
I have a SwiftUI view with: @State var url: URL? @State var isShowingBrowser: Bool func displayURL(url: URL) { self.url = url self.isShowingBrowser = true } var body: some View { Group { // ...... } .sheet(isPresented: $isShowingBrowser) { // browser view } } The first time I call displayBrowser, an empty browser sheet appears, with no URL. The second time, it works. It doesn't matter if I reorder the assignments in displayURL. It's like the view refreshes once with a nil URL and isShowingBrowser true, then refreshes again with the URL value. If I move both variable to an @Observable view model class then it works fine - that update seems to happen atomically. For my own project, the view model is the right way to do this, but I was confused by this behavior. What am I missing about SwiftUI?
Topic: UI Frameworks SubTopic: SwiftUI
2
0
375
3w
Total Newbie seeking advice on spreadsheet app
As insane as this may sound, I'm trying to write a spreadsheet app. I'm retired with 40+ years of mostly C device driver, networking type development and support. The model I'm using is Apple's Numbers and I'm currently experimenting with Table trying to mimic the look and feel of Numbers' "sheet". I believe I have two choices: I can have one Table with the first row and first column different / special and this would imply that the very first element is also special. Numbers has a circle as the top leftmost element. The top row and first column are the identifiers of the rows and columns initially starting out as A, B, C ... and 1, 2, 3 .... The advantage of this method is Table would take care that the size of the top row (the width of the columns) would match the width and position of the rest of the cells of the table. Likewise, the height of the cells in the first column would always match and align with the cells of the table. The downside with this approach is that things like sorting and selecting would need special attention. The alternative would be to have separate elements: an element in the top left corner followed by a spacer followed by a row of cells with the column identifiers A, B, C, .... Then a spacer across the entire structure. Then the there would be a column of cells for the names of the rows, a spacer, and then the actual Table of cells containing the spreadsheet itself. I am assuming that the top row with the identifiers of the columns would be a Table with one row and the first column with the identifiers of the rows would also be a Table with one column. The difficulty with this approach would be getting everything to line up correctly. I don't know if that would be hard or easy. Sometimes getting things to align is very hard, platform specific, etc. But I haven't used SwiftUI any so I don't know how hard this would be. Structurally I would prefer to take this approach. I just seems more logical and natural. Thank you for your time
Topic: UI Frameworks SubTopic: SwiftUI
0
0
123
3w
SwiftUI, macOS, PDFView, The "Remove Highlight" context menu does not work
I'm using PDFKitView: NSViewRepresentable to present the pdf page in SwiftUI. Seems we already have some useful built-in functions in the context menu. However, the highlight manipulation functions are not functional - I can neither delete the highlight annotation nor change the color/type of the current pointed highlight annotation. The "Add Note" and other page display changing functions work well.
2
1
1.2k
3w
SwiftUI animation is laggy in NSStatusItem since macOS 26 Tahoe
My app is a bit of a special case and relies on a custom view in a NSStatusItem. I use a NSHostingView and add it as a subview to my NSStatusItem's .button property. Since macOS 26 Tahoe, even simple animations like a .frame change of a Circle won't animate smoothly even though the same SwiftUI animates normally in a WindowGroup. class AppDelegate: NSObject, NSApplicationDelegate { private let statusItem: NSStatusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength) func applicationDidFinishLaunching(_ aNotification: Notification) { let subview = NSHostingView(rootView: AnimationView()) let view = self.statusItem.button view?.addSubview(subview) subview.translatesAutoresizingMaskIntoConstraints = false guard let view = view else { return } NSLayoutConstraint.activate([ subview.centerXAnchor.constraint(equalTo: view.centerXAnchor), subview.centerYAnchor.constraint(equalTo: view.centerYAnchor), subview.widthAnchor.constraint(equalToConstant: 22), subview.heightAnchor.constraint(equalToConstant: 22) ]) } } struct AnimationView: View { @State private var isTapped = false @State private var size: CGSize = .init(width: 4, height: 4) var body: some View { Circle() .fill(.pink) .frame(width: size.width, height: size.height) .frame(width: 20, height: 20) // .frame(maxHeight: .infinity) // .padding(.horizontal, 9) // .frame(height: 22) .contentShape(Rectangle()) // .background(Color.blue.opacity(0.5)) .onTapGesture { withAnimation(.interactiveSpring(response: 0.85, dampingFraction: 0.26, blendDuration: 0.45)) { // withAnimation(.spring()) { if isTapped { size = .init(width: 4, height: 4) } else { size = .init(width: 16, height: 16) } } isTapped.toggle() }} } Example project: https://app.box.com/s/q28upunrgkxyyd97ovslgud9yitqaxfk
Replies
1
Boosts
0
Views
327
Activity
2w
Tab bar animates from first tab to restored selection at launch with .tabBarMinimizeBehavior(.onScrollDown)
[Submitted as FB23998635] On iPhone, applying .tabBarMinimizeBehavior(.onScrollDown) to a SwiftUI TabView causes the native tab bar to briefly show the first declared tab before animating to the already-restored selection during app launch. The selected tab is persisted with @AppStorage and is already restored before the TabView is presented. The sample contains no explicit animations, transactions, navigation containers, loading states, asynchronous work, or post-launch selection changes. Removing .tabBarMinimizeBehavior(.onScrollDown) eliminates the launch animation entirely. Likewise, starting with .tabBarMinimizeBehavior(.never) and changing it to .onScrollDown after a one-second delay also eliminates the issue. The behavior reproduces with three simple tabs and a direct @AppStorage selection binding. ENVIRONMENT • iOS 26 & 27 REPRO STEPS Build and run the attached sample. Select the "Two" tab. Force-quit the app. Relaunch the app. Observe the tab bar during launch. ACTUAL The tab indicator initially appears on "One", the first declared tab, then animates to the correctly restored "Two" selection. EXPECTED The restored tab should be selected and stationary from the first visible frame, with no launch animation. SAMPLE CODE struct ContentView: View { private enum AppTab: String, Hashable { case one case two case three } @AppStorage("selectedGenericTab") private var selectedTab: AppTab = .three var body: some View { TabView(selection: $selectedTab) { Tab("One", systemImage: "1.circle", value: AppTab.one) { ReproTabContent(title: "One", color: .orange) } Tab("Two", systemImage: "2.circle", value: AppTab.two) { ReproTabContent(title: "Two", color: .blue) } Tab("Three", systemImage: "3.circle", value: AppTab.three) { ReproTabContent(title: "Three", color: .green) } } .tabBarMinimizeBehavior(.onScrollDown) } } private struct ReproTabContent: View { let title: String let color: Color var body: some View { ZStack { color.opacity(0.2) .ignoresSafeArea() Text(title) .font(.largeTitle) } } }
Replies
2
Boosts
0
Views
456
Activity
2w
UISearchController text field not receiving touches when another UISearchController is attached to navigationItem.searchController on iOS 26
On iOS 26, UISearchController becomes non-interactive when presenting a second UISearchController from another tab of a UITabBarController. let tabBar = UITabBarController() let first = FirstViewController() first.title = "First" let second = SecondViewController() second.title = "Second" let nav1 = UINavigationController(rootViewController: first) let nav2 = UINavigationController(rootViewController: second) nav1.tabBarItem = UITabBarItem( title: "First", image: nil, tag: 0 ) nav2.tabBarItem = UITabBarItem( title: "Second", image: nil, tag: 1 ) tabBar.viewControllers = [ nav1, nav2 ] The app has two tabs. Each tab has its own UINavigationController. Tab 1: A UISearchController is assigned to navigationItem.searchController. class FirstViewController: UIViewController { private let searchController = UISearchController( searchResultsController: nil ) override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .systemBackground searchController.obscuresBackgroundDuringPresentation = false searchController.searchResultsUpdater = self navigationItem.searchController = searchController navigationItem.hidesSearchBarWhenScrolling = false definesPresentationContext = true } } Tab 2: A button presents another UISearchController using present(_:animated:). class SecondViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .systemBackground let button = UIButton( type: .system ) button.setTitle( "Open Search", for: .normal ) button.addTarget( self, action: #selector(openSearch), for: .touchUpInside ) button.translatesAutoresizingMaskIntoConstraints = false view.addSubview(button) NSLayoutConstraint.activate([ button.centerXAnchor.constraint( equalTo: view.centerXAnchor ), button.centerYAnchor.constraint( equalTo: view.centerYAnchor ) ]) definesPresentationContext = true } @objc private func openSearch() { let searchController = UISearchController( searchResultsController: nil ) navigationController?.present( searchController, animated: true ) } } On iOS 17 and iOS 18 this works correctly. On iOS 26: The search controller appears. The Cancel button works. The search text field cannot receive touches and does not become first responder. If I remove: navigationItem.searchController = searchController from Tab 1, the search controller in Tab 2 works correctly. This looks like a UIKit regression introduced in iOS 26.
Topic: UI Frameworks SubTopic: UIKit Tags:
Replies
1
Boosts
0
Views
199
Activity
2w
popoverTips don't display for toolbar menu buttons in iOS 26.1
[Also submitted as FB20756013] A popoverTip does not display for toolbar menu buttons in iOS 26.1 (23B5073a). The same code displays tips correctly in iOS 18.6. The issue occurs both in the simulator and on a physical device. Repro Steps Build and run the Sample Code below on iOS 26.1. Observe that the popoverTip does not display. Repeat on iOS 18.6 to confirm expected behavior. Expected popoverTips should appear when attached to a toolbar menu button, as they do in iOS 18.6. Actual No tip is displayed on iOS 26.1. System Info macOS 15.7.1 (24G231) Xcode 26.1 beta 3 (17B5045g) iOS 26.1 (23B5073a) Screenshot Screenshot showing two simulators side by side—iOS 18.6 on the left (tip displayed) and iOS 26.1 on the right (no tip displayed). Sample code import SwiftUI import TipKit struct PopoverTip: Tip { var title: Text { Text("Menu Tip") } var message: Text? { Text("This tip displays on iOS 18.6, but NOT on iOS 26.1.") } } struct ContentView: View { var tip = PopoverTip() var body: some View { NavigationStack { Text("`popoverTip` doesn't display on iOS 26.1 but does in iOS 18.6") .padding() .toolbar { ToolbarItem(placement: .topBarTrailing) { Menu { Button("Dismiss", role: .cancel) { } Button("Do Nothing") { } } label: { Label("More", systemImage: "ellipsis") } .popoverTip(tip) } } .navigationTitle("Popover Tip Issue") .navigationBarTitleDisplayMode(.inline) } } }
Replies
6
Boosts
3
Views
938
Activity
2w
Unable to use AppIntents
Hi, I'm trying to add Shortcuts using AppIntents but unable to get past this error: 'AppShortcutsProvider' property 'appShortcuts' requires builder syntax This is the AppShortcutsProvider struct: import AppIntents struct MyAppShortcuts: AppShortcutsProvider { @AppShortcutsBuilder static var appShortcuts: [AppShortcut] { AppShortcut( intent: OpenDashboardIntent(), phrases: [ "Open dashboard in \(.applicationName)", "Show my \(.applicationName) dashboard" ], shortTitle: "Open Dashboard", systemImageName: "square.grid.2x2" ) } } And I have only one intent: import AppIntents struct OpenDashboardIntent: AppIntent { static var title: LocalizedStringResource = "Open Dashboard" static var openAppWhenRun: Bool = true @MainActor func perform() async throws -> some IntentResult & ProvidesDialog { return .result(dialog: "Opening dashboard") } } I searched the error online but the fixes were to use @AppShortcutsBuilder and skipping commas in case of registering multiple app intents - I'm already following all that. What am I missing? Thanks.
Replies
0
Boosts
0
Views
403
Activity
2w
Inspector Panel Visual UI
How can I get the inspector panel on the Mac to be respected by the toolbar? In Xcode and Pages, the inspector panel runs the entire length of the app so that everything slides over when it's invoked. But in my testing, the toolbar always overlaps the inspector. import SwiftUI @main struct MyApp: App { var body: some Scene { WindowGroup { ContentView() } } } struct ContentView: View { @State private var selectedItem: String? = "Page 1" @State private var inspectorVisible = true let items = ["Page 1", "Page 2", "Page 3"] var body: some View { NavigationSplitView { List(items, id: \.self, selection: $selectedItem) { item in Label(item, systemImage: "doc") } } detail: { Text(selectedItem ?? "Nothing selected") .font(.title2) .foregroundStyle(.secondary) .inspector(isPresented: $inspectorVisible) { List { Section("Properties") { LabeledContent("Width", value: "100") LabeledContent("Height", value: "200") } Section("Style") { LabeledContent("Color", value: "Blue") LabeledContent("Opacity", value: "100%") } } .scrollContentBackground(.hidden) } } .toolbar { ToolbarItemGroup(placement: .principal) { Button("Draw", systemImage: "pencil") {} Button("Shape", systemImage: "circle") {} Button("Text", systemImage: "textformat") {} } ToolbarItem () { Button("Share", systemImage: "square.and.arrow.up") {} } ToolbarItem() { Button("Inspector", systemImage: "sidebar.right") { inspectorVisible.toggle() } } } .navigationTitle("My Project") } } #Preview { ContentView() .frame(width: 1100, height: 600) }
Topic: UI Frameworks SubTopic: SwiftUI
Replies
0
Boosts
0
Views
282
Activity
2w
Distinguishing background from user app launches
When adopting the Scene Delegate, the applicationState changes from indicating app state to indicating scene state. I previously used this as a signal to determine whether my iOS app was launched in the background or launched by the user. Given the change, it seems like applicationState should no longer be used in that manner in the App Delegate. Would you recommend using UIApplication.shared.backgroundTimeRemaining to distinguish a background launch from a user launch? assuming this is a very large value for user launches. Are there corner cases that I may not expect?
Replies
1
Boosts
0
Views
535
Activity
3w
Can't Drag and Drop a file promise into /tmp
This happens with my own code as well as with the Apple example code here: Supporting Drag and Drop Through File Promises When dragging a file promise, the above example code will fail if the destination is in /tmp. It will print out the following message to the console: An error occurred while attempting to get a unique promise file URL. Error: Did not receive a valid URL. It doesn't seem to fail if you create a directory inside /tmp and drop into that. But dropping in /tmp fails 100% of the time. And it fails for MacOS Versions from Sequoia all the way up to the most recent Golden Gate beta. Using /tmp as a destination should most certainly be allowed, but if for some reason it isn't, is there any way in my own code to detect the drop destination and perhaps warn the user that they need to drop somewhere else? To reproduce this error, use the following steps: Download the Apple example code from the link above Open the project in Xcode, build it, and run it Drag any image into the example app's main window Open a Finder window and navigate to /tmp Drag the image from the example app into the /tmp directory in the Finder window. You will see the above error in the Xcode console and the drop will fail.
Topic: UI Frameworks SubTopic: AppKit
Replies
0
Boosts
0
Views
392
Activity
3w
iOS 27 – What changes are mandatory to support Liquid Glass?
We're preparing our SDK and host applications for iOS 27 and would like to understand the mandatory requirements for supporting the new Liquid Glass design. Beyond building with the iOS 27 SDK, are there any required implementation or migration steps (UIKit or SwiftUI) that developers must adopt to ensure full compatibility? Are there any behaviors or APIs that require explicit changes, or does the system automatically handle Liquid Glass for standard controls? We're specifically interested in the minimum required changes for compliance and compatibility, rather than optional design enhancements. Thanks in advance for any guidance.
Topic: UI Frameworks SubTopic: General
Replies
1
Boosts
0
Views
214
Activity
3w
What's the preferred way enable scroll behind tab bar in nested ScrollView in SwiftUI
I am having a root TabView with tabs. One of the tabs has a TabBar with page style as the root view and each Page has a ScrollView. Unfortunately the scroll view get's clipped by the parent TabView size. But I want to make the ScrollView content to go behind the root TabView's tab bar like it would work if I would have the ScrollView as direct child to the root TabBar I tried using ignoreSafeArea on the page style TabView and there are other weird bugs, it stops reacting to the Binding pageIndex I am having as a State. The custom page index view disappears Sample code: https://github.com/BProg/TabViewScrollViewBug.git
Replies
2
Boosts
0
Views
165
Activity
3w
SwiftUI's `scrollTo(id:anchor:)` doesn't work if the ScrollView is scrolling
Can somebody tell me if I'm doing something wrong or SwiftUI's scrollTo(id:anchor:) just doesn't work if the ScrollView is scrolling? I have a trivial example that demonstrates the issue: import SwiftUI @main struct MyApp: App { var body: some Scene { WindowGroup { ContentView() } } } struct Item: Identifiable { let id = UUID() let timestamp: Date let text: String } struct ContentView: View { @State private var items: [Item] = (0...10_000).map{ .init(timestamp: Date(), text: "Row \($0)") } @State private var scrollPosition = ScrollPosition(idType: Item.ID.self) @State private var newMessage: String = "" var body: some View { ScrollView { LazyVStack { ForEach(items) { item in ItemView(item: item) } }.scrollTargetLayout() } .defaultScrollAnchor(.bottom, for: .initialOffset) .scrollPosition($scrollPosition, anchor: .bottom) .safeAreaBar(edge: .bottom) { HStack { TextField("Type here", text: $newMessage, axis: .vertical) .textFieldStyle(.roundedBorder) Button("Send", action: { let trimmed = newMessage.trimmingCharacters(in: .whitespacesAndNewlines) guard !trimmed.isEmpty else { return } newMessage = "" items.append(.init(timestamp: .now, text: trimmed)) withAnimation(.smooth) { scrollPosition.scrollTo(id: items.last!.id, anchor: .bottom) } }) }.padding() } } } struct ItemView: View { let item: Item var body: some View { VStack(alignment: .leading) { Text(item.text) Text(item.timestamp.formatted()) }.padding() .frame(maxWidth: .infinity, alignment: .leading) .background(Color(red: .random(in: 0...1), green: .random(in: 0...1), blue: .random(in: 0...1))) } } #Preview { ContentView() }
Replies
2
Boosts
0
Views
226
Activity
3w
How to send a message from menu item in SwiftUI App to ContentView
I'm just not getting it. My app adds a custom Import menu item to the File menu. I want to have it tell the sole ContentView to run the fileImporter. Here's how I have it set up. Changing the showFileImporter variable to supposed to make stuff happen, but it doesn't change. @main struct Blah: App { @State public var contentView = ContentView(); var body:some Scene { WindowGroup { // ContentView() // It started out defining the content like normal, but I saw somewhere that if I declared it as a var up top, then I'd have an actual object that I could tell to do things, like calling the importTerms() method below. self.contentView } .commands { CommandGroup(after:.newItem) { Button("Import…") { contentView.importTerms(); } } } } struct ContentView: View { @State private var showFileImporter = false; var body: some View { VStack { ...stuff... } } .fileImporter(isPresented:$showFileImporter, allowedContentTypes:[.text], allowsMultipleSelection:false) { result in } public func importTerms() { print("\(showFileImporter)"); // ->false showFileImporter = true; print("\(showFileImporter)"); // ->yep, still false } } But it doesn't work. It calls importTerms(), and a breakpoint inside that method does get hit. But it doesn't change the value of showFileImporter and the fileImporter never appears. What kind of weird world has Swift made where setting a variable to true doesn't set it to true and there's no error at build or runtime?
Topic: UI Frameworks SubTopic: SwiftUI
Replies
15
Boosts
1
Views
362
Activity
3w
App hangs on navigation bar rendering cycle
We are currently having an issue with our app hanging for some (not all) of our iOS 26.x users. The hang lasts long enough for the system to kill the app after a while. As of now we are unable to reproduce the issue on our own test devices, yet users dealing with the issue can produce it consistently. Looking at the stack traces we managed to retrieve, the hangup seems to occur in the layout rendering cycle of the navigation bar in the UINavigationController. The hangup doesn't happen at the exact same stack trace every time. But it always seems to be in the rendering cycle. Stack trace 1 Stack trace 2 Stack trace 3 Since the issue not reproducable in our own test environment it's hard to properly debug. The only adjustments to the navigationbar/navigationitem in our code is setting the title and a few bar buttons: self.navigationItem.title = NSLocalizedString("main_list_title", comment: "") let cancelItem = UIBarButtonItem(barButtonSystemItem: .stop, target: self, action: #selector(cancelListSelection)) let addPostItem = UIBarButtonItem(image: UIImage(named: "AddButton"), style: .plain, target: self, action: #selector(addItemTapped)) let extraMenuItem = UIBarButtonItem(image: UIImage(named: "ExtraButton"), style: .plain, target: self, action: #selector(extraItemTapped)) self.navigationItem.setLeftBarButton(cancelItem, animated: true) self.navigationItem.setRightBarButtonItems([addPostItem, extraMenuItem], animated: true) let previousButton = UIBarButtonItem(image: UIImage(named: "LeftArrow"), style: .plain, target: self, action: #selector(openPrevious)) let nextButton = UIBarButtonItem(image: UIImage(named: "RightButton"), style: .plain, target: self, action: #selector(openNext)) self.setToolbarItems([previousButton, nextButton], animated: true) And for one or two controllers the title is replaced by a UISegmentControl: let segControl = UISegmentedControl(items: ["1", "2", "3"]); segControl.selectedSegmentIndex = 0 segControl.addTarget(self, action: #selector(segmentValueChanged), for: .valueChanged) self.navigationItem.titleView = segControl Is anyone familiar with hangs at these particular stack traces and their cause?
Topic: UI Frameworks SubTopic: UIKit Tags:
Replies
4
Boosts
0
Views
597
Activity
3w
SwiftUI `List` incorrectly reuses stale `Equatable` objects when redrawing
Hi, We have found a nasty issue with SwiftUI List and Equatable reference types. In such scenarios List might resurface stale objects from some internal cache when inserting new equal instances, which can lead to outdated cells on screen. Detailed information can be found in our bug report (FB23923342). Since List is quite a widespread component we thought dropping a few lines here in addition to our report could be helpful, especially if you have been bitten by this issue in the past.
Replies
0
Boosts
0
Views
162
Activity
3w
CarPlay UI Issues in iOS 26: CPListItem accessoryImage Misplaced and Display Problems
previously, setting accessoryImage would display the image on the far right. Now, it appears right next to the detailText, and the image is extremely small. I am already using the latest beta, but the problem still exists.
Topic: UI Frameworks SubTopic: UIKit Tags:
Replies
2
Boosts
0
Views
359
Activity
3w
Adding top content inset to an NSScrollView below an NSSplitViewItemAccessoryViewController in a sidebar
I have a question about NSSplitViewItemAccessoryViewController, introduced with the new design since macOS 26, and how it interacts with NSScrollView content insets. My app has a typical three-pane window whose content view controller is an NSSplitViewController subclass. The sidebar contains a tab view with a segmented control, similar to Xcode, for switching between different sidebar panes. Each pane contains an NSScrollView whose content can be scrolled. Before macOS 26, I placed the segmented control directly inside the sidebar view. To adopt the new scroll-edge effect and allow the sidebar content to extend visually into the window title bar, I moved the segmented control into an NSSplitViewItemAccessoryViewController. However, with this layout, the scroll view starts immediately below the segmented control, which feels visually cramped. I'd like to add a few points of top inset before the document view begins. Previously, I achieved this by setting: scrollView.additionalSafeAreaInsets.top However, this now causes the accessory view's scroll-edge effect to extend into the additional safe-area inset, producing an awkward blurred region underneath the segmented control. Ideally, I'd like the scroll view to begin directly below the segmented control while still having a small inset before the document content, with the scroll-edge effect ending exactly at the bottom of the accessory view. In addition to additionalSafeAreaInsets, I tried the following approaches, but neither produced the desired result: Set scrollView.automaticallyAdjustsContentInsets to false and specify scrollView.contentInsets.top. This disables the automatic safe-area adjustment, causing the entire scroll view to move upward underneath the accessory view. Set scrollView.contentView.automaticallyAdjustsContentInsets to false and specify scrollView.contentView..contentInsets.top. This produces the same result as above. Set the accessory view's preferredScrollEdgeEffectStyle to .soft. The segmented control becomes too transparent, making its unselected labels difficult to read. Xcode's sidebar appears to achieve the behavior I'm looking for. What is the recommended way to implement this layout on macOS 26 and 27? Xcode's sidebar (macOS 26) My app's sidebar (macOS 26, work in develop) with additionalSafeAreaInsets
Topic: UI Frameworks SubTopic: AppKit
Replies
0
Boosts
0
Views
184
Activity
3w
Timing issue with updating two state variables
I have a SwiftUI view with: @State var url: URL? @State var isShowingBrowser: Bool func displayURL(url: URL) { self.url = url self.isShowingBrowser = true } var body: some View { Group { // ...... } .sheet(isPresented: $isShowingBrowser) { // browser view } } The first time I call displayBrowser, an empty browser sheet appears, with no URL. The second time, it works. It doesn't matter if I reorder the assignments in displayURL. It's like the view refreshes once with a nil URL and isShowingBrowser true, then refreshes again with the URL value. If I move both variable to an @Observable view model class then it works fine - that update seems to happen atomically. For my own project, the view model is the right way to do this, but I was confused by this behavior. What am I missing about SwiftUI?
Topic: UI Frameworks SubTopic: SwiftUI
Replies
2
Boosts
0
Views
375
Activity
3w
Total Newbie seeking advice on spreadsheet app
As insane as this may sound, I'm trying to write a spreadsheet app. I'm retired with 40+ years of mostly C device driver, networking type development and support. The model I'm using is Apple's Numbers and I'm currently experimenting with Table trying to mimic the look and feel of Numbers' "sheet". I believe I have two choices: I can have one Table with the first row and first column different / special and this would imply that the very first element is also special. Numbers has a circle as the top leftmost element. The top row and first column are the identifiers of the rows and columns initially starting out as A, B, C ... and 1, 2, 3 .... The advantage of this method is Table would take care that the size of the top row (the width of the columns) would match the width and position of the rest of the cells of the table. Likewise, the height of the cells in the first column would always match and align with the cells of the table. The downside with this approach is that things like sorting and selecting would need special attention. The alternative would be to have separate elements: an element in the top left corner followed by a spacer followed by a row of cells with the column identifiers A, B, C, .... Then a spacer across the entire structure. Then the there would be a column of cells for the names of the rows, a spacer, and then the actual Table of cells containing the spreadsheet itself. I am assuming that the top row with the identifiers of the columns would be a Table with one row and the first column with the identifiers of the rows would also be a Table with one column. The difficulty with this approach would be getting everything to line up correctly. I don't know if that would be hard or easy. Sometimes getting things to align is very hard, platform specific, etc. But I haven't used SwiftUI any so I don't know how hard this would be. Structurally I would prefer to take this approach. I just seems more logical and natural. Thank you for your time
Topic: UI Frameworks SubTopic: SwiftUI
Replies
0
Boosts
0
Views
123
Activity
3w
Vertical layout breaks after app switching from active keyboard context.
When switching to a SwiftUI app (built with Xcode 26.5) from an app with an active keyboard, the target app's tab bar incorrectly floats above the keyboard safe area. This layout issue occurs even though the target app does not display a keyboard and contains only a tab bar and scroll views.
Replies
2
Boosts
0
Views
351
Activity
3w
SwiftUI, macOS, PDFView, The "Remove Highlight" context menu does not work
I'm using PDFKitView: NSViewRepresentable to present the pdf page in SwiftUI. Seems we already have some useful built-in functions in the context menu. However, the highlight manipulation functions are not functional - I can neither delete the highlight annotation nor change the color/type of the current pointed highlight annotation. The "Add Note" and other page display changing functions work well.
Replies
2
Boosts
1
Views
1.2k
Activity
3w