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

Created

NSTextAttachment.character symbol suddenly not available anymore resulting in compiler error
I published the latest update of my AppKit app in September with macOS 26.0. I just wanted to create a new update, but compiling on macOS 26.4 now fails because of the symbol NSTextAttachment.character which is referenced in my code. The error is Type 'NSTextAttachment' has no member 'character' I've never experienced before that a symbol suddenly is not available anymore without even a deprecation notice from one OS release to the next, let alone a minor release. Is this a bug in macOS or Xcode, or should I start worrying about symbols becoming unavailable anytime?
3
0
228
1w
Potentially Unfair Limitation for Third-Party Keyboard Developers
When developing a custom keyboard on iOS, even after enabling Full Access (RequestsOpenAccess = true), it is still not possible to record audio — the recording simply does not start. This is despite the fact that: the user is explicitly warned the user provides informed consent by enabling Full Access According to Apple’s documentation: https://developer.apple.com/documentation/uikit/configuring-open-access-for-a-custom-keyboard “However, with RequestsOpenAccess set to true, the keyboard has all the capabilities in the preceding list.” At the same time, the preceding list includes: “No access to microphone and speaker” This creates ambiguity. The wording suggests that enabling Full Access should lift prior restrictions, yet in practice, microphone access remains unavailable to third-party keyboards. Why this is concerning With Full Access enabled, a keyboard already has: network access the ability to transmit user input From a privacy standpoint, this is already highly sensitive. Preventing microphone access while allowing these capabilities appears inconsistent. Meanwhile, Apple’s own system keyboard supports voice dictation, which creates a functional gap between first-party and third-party keyboards. Competition perspective This raises a broader question about equal access to platform capabilities. Restricting third-party keyboards from using the microphone — while first-party solutions can — may be seen as: unequal treatment of developers a limitation of competition in input methods Such differences are increasingly scrutinized under EU regulations like the Digital Markets Act and Article 102 TFEU, which emphasize fair access to platform features and prohibit self-preferencing by dominant platforms. Request for clarification Is microphone access intentionally restricted for all third-party keyboards, even with Full Access enabled? If so, what is the technical or policy justification? Are there plans to provide a secure and user-consented way to enable audio input for custom keyboards? Clarification on this would help developers better understand platform limitations and design decisions.
0
0
120
1w
UITextView cursor sometimes jumps up when pressing arrow down key and setting typingAttributes
My app uses TextKit 1 and unfortunately still cannot migrate to TextKit 2 because of some bugs (for instance in FB17103305 I show how NSTextView.shouldDrawInsertionPoint has no effect, but I opened that feedback exactly one year ago and it still has no answer). Unfortunately TextKit 1 has another bug which causes the text cursor to jump unpredictably up or down when pressing the arrow keys and setting UITextView.typingAttributes. Run the code below on iPhone 17 Pro Max Simulator. Scroll the text down until you see “Header 2”. Place the text cursor after “# “. Press the arrow down key twice to move the cursor two lines down. The cursor moves to the top of the view instead. Continuing to press the arrow keys up and down results in the cursor sometimes moving as expected, other times jumping around wildly. Does anyone know a workaround? I created FB22382453. class TextView: UITextView, UITextViewDelegate { override func awakeFromNib() { let _ = layoutManager delegate = self let header = textAttributes(fontSize: 30) let body = textAttributes(fontSize: 15) let string = NSMutableAttributedString(string: String(repeating: "a", count: 2681) + "\n", attributes: body) string.append(NSAttributedString(string: """ # Header 1 """, attributes: header)) string.append(NSMutableAttributedString(string: String(repeating: "a", count: 5198) + "\n", attributes: body)) string.append(NSAttributedString(string: """ # Header 2 """, attributes: header)) string.append(NSMutableAttributedString(string: String(repeating: "a", count: 7048) + "\n", attributes: body)) textStorage.setAttributedString(string) } func textViewDidChangeSelection(_ textView: UITextView) { typingAttributes = textStorage.attributes(at: selectedRange.location - 1, effectiveRange: nil) } private func textAttributes(fontSize: Double) -> [NSAttributedString.Key: Any] { var textAttributes = [NSAttributedString.Key: Any]() textAttributes[.font] = UIFont(name: "Courier", size: fontSize) let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.minimumLineHeight = round(fontSize * 1.3) paragraphStyle.maximumLineHeight = paragraphStyle.minimumLineHeight textAttributes[.paragraphStyle] = paragraphStyle return textAttributes } }
Topic: UI Frameworks SubTopic: UIKit Tags:
0
0
108
1w
PDFView left-anchors to window edge instead of centering between sidebar and inspector (macOS Tahoe)
I'm building a document viewer on macOS Tahoe with a 3-column NSSplitViewController (sidebar | detail | inspector), trying to replicate how Preview displays PDFs with the page centered in the visible gap between the panels, with content bleeding under them when panning or zooming. I'm using the approach from Build an AppKit app with the new design (WWDC25): detailItem.automaticallyAdjustsSafeAreaInsets = true safeAreaInsets reports the correct values (e.g. left: 208, right: 240), and the frame does extend under both panels. But PDFView with autoScales = true anchors the page to the left edge of the window instead of centering it in the visible gap between the sidebar and inspector. I can get the page to center correctly by constraining PDFView to view.safeAreaLayoutGuide, but then content no longer extends under the panels when panning or zooming, which defeats the whole purpose. What's the correct way to center PDFView content within the visible gap while keeping the frame full-width so content bleeds under the panels? I've attached pictures of how Preview does it.
Topic: UI Frameworks SubTopic: AppKit
0
0
75
1w
UIScrollView Fast Scrolling have it scroll to the beginning when i press dpad to left while vertical scrolling
I'm triaging the issue with the fast scrolling on UIScrollView and I'm really upset how little to no info this component is on the internet. Like i disabled scrolling and yet after holding the dpad down to scroll downward eventually the fast scroll mechanism is used. The issue I have is that I have a setup where the scrollview scrolling is disabled and whenever cells are focused it'll scroll to the cell's position for that cells to focused on top left side of the scrollview. I start off with the cell placed at position x of 1000. I scroll down enough to enable fast scrolling. While fast scrolling vertically, i press left a couple of time and it somewhat scroll horizontally. Actual scrollView index is suddenly placed to x:0 instead of let say x:950-1000 Expected should be scrolled to the left of cell at position x 1000. Attached the stack trace and the log showcasing it and run it on simulator tvos 26.2. Initial properties of the scrollview we set up scroll = [UIScrollView new]; scroll.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; scroll.automaticallyAdjustsScrollIndicatorInsets = false; [scroll setDirectionalLockEnabled:TRUE]; [scroll setContentInset:UIEdgeInsetsMake(0, 0, 0, 0)]; scroll.bounces = FALSE; scroll.delaysContentTouches = FALSE; scroll.showsVerticalScrollIndicator = FALSE; scroll.showsHorizontalScrollIndicator = FALSE; The plan for me at least is to somehow disable the horizontal scrolling interaction of it when fast scrolling is enabled, without accessing the private components of it.
0
0
79
1w
Scene resizing on iPad breaks UIPageViewController's setViewControllers
The following is verbatim of a feedback report (FB22367951) I submitted, shared here as someone else might be interested to see it. I have reproduced this bug on iPadOS 26.3.1 (a) and 26.4. During scene resizing on iPad, UIPageViewController's setViewControllers method fails to do its work. The navigation starts and for a brief moment you can see the new view controller coming from the expected direction, but shortly after it fails and stays on the same [current] view controller. It doesn't even call the completion handler when it fails. When the navigation succeeds (due to not resizing a scene during the navigation) after previously failing at least once, the completion handler is sometimes called more than once. I have created a demo project, which I have pushed to this repo: https://github.com/galijot/SceneResize-Breaks-UIPageViewController I have also attached a zip of the project to this report.
0
0
80
1w
MapKit in SwiftUI
Anyone worked with MapKit's MapCameraPosition in SwiftUI? I'm building a navigation app and ran into a limitation I can't find a clean solution for when using .userLocation(followsHeading: true) MapKit takes full control of the camera, smooth heading tracking, follows the user automatically. Perfect. But there's no way to set a custom pitch (tilt) on it. The only initializer available is... .userLocation(followsHeading: true, fallback: .automatic) No pitch, no distance parameters.... The workaround I found is setting .camera(MapCamera(..., pitch: 60)) first, waiting 200ms, then switching to .userLocation(followsHeading: true), MapKit inherits the pitch from the rendered camera state before handing off to user tracking.... It works, but it's clearly exploiting an undocumented behaviour in MapKit's state machine rather than a proper API Has anyone found a cleaner way to achieve this? Or is UIViewRepresentable wrapping MKMapView the only proper solution? It would be awesome to have something like this cameraPosition = .userLocation( followsHeading: true, pitch: 60, distance: 800, fallback: .automatic )
1
0
133
2w
NavigationLink selection in DisclosureGroup not working with .draggable modifier
NavigationLink selection in DisclosureGroup not working with .draggable modifier This was recently also posted here: https://stackoverflow.com/questions/79914290/ I am playing around with a tree data structure with folders and entries.I would like to add dragging of entries and folders between folders, using .draggable and dropDestination. In my current code, dragging works, but selection of entries no longer works, except if I click outside of the Text If I comment out .draggable(subfolder.name) in func FolderRow(), selection works as expected. How can I make sure both selection and drag and drop works for both folders and entries? I also tried using Transferable and Codable, but I get the same result. Here is an MRE: import SwiftData import SwiftUI @Model final class Folder { @Attribute(.unique) var name: String // Parent var parentFolder: Folder? // Child folders @Relationship(deleteRule: .cascade, inverse: \Folder.parentFolder) var subfolders: [Folder] = [] // Leaf entries @Relationship(deleteRule: .cascade, inverse: \Entry.folder) var entries: [Entry] = [] init(name: String, parentFolder: Folder? = nil) { self.name = name self.parentFolder = parentFolder } } @Model final class Entry { @Attribute(.unique) var name: String var detail: String var folder: Folder? // recursive relationship init(name: String, detail: String) { self.name = name self.detail = detail } } @main struct TestMacApp: App { var body: some Scene { WindowGroup { SidebarView() .modelContainer(for: Folder.self) } } } struct SidebarView: View { @Environment(\.modelContext) private var context @Query(filter: #Predicate<Folder> { $0.parentFolder == nil }) private var rootFolders: [Folder] var body: some View { NavigationSplitView { List { ForEach(rootFolders) { folder in FolderRow(folder: folder) .draggable(folder.name) } } } detail: { Text("detail") } .onAppear { seed() } } } struct FolderRow: View { @Environment(\.modelContext) private var context var folder: Folder @State private var isExpanded: Bool = true var body: some View { DisclosureGroup(isExpanded: $isExpanded) { // Subfolders ForEach(folder.subfolders) { subfolder in FolderRow(folder: subfolder) .draggable(subfolder.name) // disabling this line fixes the selection } // Entries (leaf nodes) ForEach(folder.entries) { entry in NavigationLink(destination: EntryDetail(entry: entry)) { EntryRow(entry: entry) } .draggable(entry.name) } } label: { Label(folder.name, systemImage: "folder") } .dropDestination(for: String.self) { names, _ in return handleDrop(of: names) } } } struct EntryRow: View { var entry: Entry var body: some View { Text(entry.name) } } struct EntryDetail: View { var entry: Entry var body: some View { Text(entry.detail) } } extension FolderRow { private func handleDrop(of names: [String]) -> Bool { do { for name in names { if let droppedEntry = try context.fetchFilteredModel(filter: #Predicate<Entry> { x in x.name == name }) { droppedEntry.folder = folder print("dropped \(droppedEntry.name) on \(folder.name)") } else if let droppedFolder = try context.fetchFilteredModel(filter: #Predicate<Folder> { x in x.name == name }) { if droppedFolder.parentFolder != nil && droppedFolder != folder { droppedFolder.parentFolder = folder print("dropped \(droppedFolder.name) on \(folder.name)") } } } return true } catch { debugPrint(error.localizedDescription) return false } } } extension SidebarView { private func seed() { do { // delete current models for folder: Folder in try context.fetchAllModels() { context.delete(folder) } try context.save() let rootFolder = Folder(name: "Root") let entry1 = Entry(name: "One", detail: "Detail One") let entry2 = Entry(name: "Two", detail: "Detail Two") rootFolder.entries.append(contentsOf: [entry1, entry2]) let subFolder1 = Folder(name: "Sub1", parentFolder: rootFolder) let entry3 = Entry(name: "Three", detail: "Detail Three") let entry4 = Entry(name: "Four", detail: "Detail Four") subFolder1.entries.append(contentsOf: [entry3, entry4]) let subFolder2 = Folder(name: "Sub2", parentFolder: rootFolder) let entry5 = Entry(name: "Five", detail: "Detail Five") let entry6 = Entry(name: "Six", detail: "Detail Six") subFolder2.entries.append(contentsOf: [entry5, entry6]) context.insert(rootFolder) } catch { debugPrint(error) } } } extension ModelContext { // convenience methods func fetchAllModels<M>() throws -> [M] where M: PersistentModel { let fetchDescriptor = FetchDescriptor<M>() return try fetch(fetchDescriptor) } func fetchFilteredModels<M>(filter: Predicate<M>) throws -> [M] where M: PersistentModel { let fetchDescriptor = FetchDescriptor<M>(predicate: filter) return try fetch(fetchDescriptor) } func fetchFilteredModel<M>(filter: Predicate<M>) throws -> M? where M: PersistentModel { return try fetchFilteredModels(filter: filter).first } }
Topic: UI Frameworks SubTopic: SwiftUI
1
0
188
2w
Left navigation bar items become invisible after rotating device and presenting detail view in split view
A user of my app, whose main view is a split view, reported an issue which causes the left navigation bar items to disappear without apparent reason if they rotate the device and later show the detail view, preventing them from using the back button to show the root view again. Am I doing something wrong or is it a bug? I can reproduce the issue with the following steps: Create a new document-based iOS app (as it uses scenes by default, as opposed to a regular app). Paste the code below. In the target build settings, delete "Launch Screen Interface File Base Name" and set "Launch Screen (Generation)" to YES. Without this step, for some reason, the issue doesn't happen. Launch the app in iPhone Simulator. Tap the top left button to show the root view, then the “detail” button to show the detail view. The left navigation bar button is still visible. Rotate the Simulator window right, then left again. Tap the top left button to show the root view, then the “detail” button to show the detail view. Now the left navigation bar button is invisible. Rotating the device right and left again solves the issue. I filed FB22363118. class SceneDelegate: UIResponder, UIWindowSceneDelegate { var window: UIWindow? func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { window = UIWindow(windowScene: scene as! UIWindowScene) let split = SplitViewController() window!.rootViewController = split window!.makeKeyAndVisible() split.showDetail() } } class SplitViewController: UISplitViewController, UISplitViewControllerDelegate { var detailNavigationViewController: UINavigationController! init() { super.init(nibName: nil, bundle: nil) detailNavigationViewController = UINavigationController(rootViewController: DetailViewController()) viewControllers = [UINavigationController(rootViewController: RootViewController())] } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } func showDetail() { showDetailViewController(detailNavigationViewController, sender: nil) } func showRoot() { (viewControllers.first as? UINavigationController)?.popViewController(animated: true) } } class RootViewController: UIViewController { override func loadView() { navigationItem.title = "root" let button = UIButton(primaryAction: UIAction(handler: { [self] _ in (splitViewController as! SplitViewController).showDetail() })) button.setTitle("detail", for: .normal) view = button } } class DetailViewController: UIViewController { override func loadView() { navigationItem.title = "detail" view = UIView() registerForTraitChanges([UITraitHorizontalSizeClass.self]) { (self: Self, previousTraitCollection) in if previousTraitCollection.horizontalSizeClass != self.traitCollection.horizontalSizeClass { self.updateBarButtons() } } updateBarButtons() } private func updateBarButtons() { navigationItem.leftBarButtonItem = UIBarButtonItem(primaryAction: UIAction(image: UIImage(systemName: "sidebar.leading")) { [self] _ in (self.splitViewController as! SplitViewController).showRoot() }) navigationItem.rightBarButtonItem = UIBarButtonItem(title: "right") } }
Topic: UI Frameworks SubTopic: UIKit Tags:
0
0
67
2w
How to recreate Apple Music mini player transition in SwiftUI
Hello, I am building an audio player app in SwiftUI and trying to recreate the behavior of Apple Music's mini player and full player. I'm struggling to get the animation to seamlessly transition between the mini player and the full player. Currently, it feels disconnected and doesn't resemble the smooth animation seen in Apple Music. What I want to achieve: Full player that expands/collapses from/to the mini player Smooth artwork transition between both states Drag down to collapse the full player Support both newer APIs like tabViewBottomAccessory and older iOS versions Questions: What is the best way to build this transition in SwiftUI? Should I use matchedGeometryEffect or something else? Should this be a custom container instead of fullScreenCover? How would you support both new and older iOS versions? What is the best way to implement drag to dismiss? Thanks for any help! Example code: struct ContentView: View { @State private var isFullPlayerPresented = false var body: some View { TabView { Tab("Home", systemImage: "house") { Text("Home") .frame(maxWidth: .infinity, maxHeight: .infinity) .background(.green) } Tab("Library", systemImage: "rectangle.stack.fill") { Text("Library") .frame(maxWidth: .infinity, maxHeight: .infinity) .background(.brown) } } .tabViewBottomAccessory(isEnabled: !isFullPlayerPresented) { MiniPlayerView(isFullPlayerPresented: $isFullPlayerPresented) } .fullScreenCover(isPresented: $isFullPlayerPresented) { // Maybe it's not a full screen cover presentation in Apple Music? FullPlayerView(isFullPlayerPresented: $isFullPlayerPresented) } } } Mini player: struct MiniPlayerView: View { @Binding var isFullPlayerPresented: Bool var body: some View { Button { isFullPlayerPresented = true } label: { HStack { Image(systemName: "photo") .resizable() .scaledToFit() .frame(width: 30, height: 30) .clipShape(.rect(cornerRadius: 8)) Spacer() Text("Tap to open full player") Spacer() Button("", systemImage: "play.fill", action: {}) } .padding(.horizontal) .padding(.vertical, 4) } .foregroundStyle(.white) } } Full player: struct FullPlayerView: View { @Binding var isFullPlayerPresented: Bool var body: some View { // This art work needs to snaps to the artwork in mini player Image(systemName: "photo") .resizable() .scaledToFit() .frame(width: 250, height: 250) .clipShape(.rect(cornerRadius: 20)) .frame(maxWidth: .infinity, maxHeight: .infinity) .background(.red) .overlay(alignment: .topTrailing) { Button(role: .close) { isFullPlayerPresented = false } .foregroundStyle(.white) .padding() } } }
2
0
275
2w
NSBrowser -deselectAll: broken on macOS Tahoe 26.4
So if I have a selection in NSBrowser. I hit Option+Command+A to invoke "Deselect" the selection in the parent for the last column drops its selections, as expected. But the column doesn't drop off the browser. The delegate method (void)browser:(NSBrowser *)browser didChangeLastColumn:(NSInteger)oldLastColumn toColumn:(NSInteger)column NS_SWIFT_UI_ACTOR; Never fires (since the column isn't dropped off). But we have. dangling last column with no selection in the previous column. Now if there's enough room for me to deselect by clicking the background, the last column drops off, as expected. This seems to be fairly new? Anyone else experiencing this? These 26point updates seem to keep punching me in the face. And yes. deselect all seems somewhat broken in Column view in the Finder as well, but in a seemingly different way. In Finder it just seems to change the selection color like it deactivated the window but doesn't drop the selection. For me, the selection IS dropped but the column remains visible. Maybe they are using Cocoa bindings or something that resyncs the selection after the mess up. I dk.
0
0
133
2w
NavigationSplitView no longer pops back to the root view when selection = nil in iOS 26.4 (with a nested TabView)
In iOS 26.4 (iPhone, not iPad), when a NavigationSplitView is combined with a nested TabView, it no longer pops back to the root sidebar view when the List selection is set to nil. This has been working fine for at least a few years, but has just stopped working in iOS 26.4. Here's a minimal working example: import SwiftUI struct ContentView: View { @State var articles: [Article] = [Article(articleTitle: "Dog"), Article(articleTitle: "Cat"), Article(articleTitle: "Mouse")] @State private var selectedArticle: Article? = nil var body: some View { NavigationSplitView { TabView { Tab { List(articles, selection: $selectedArticle) { article in Button { selectedArticle = article } label: { Text(article.title) } } } label: { Label("Explore", systemImage: "binoculars") } } } detail: { Group { if let selectedArticle { Text(selectedArticle.title) } else { Text("No selected article") } } .navigationBarBackButtonHidden(true) .toolbar { ToolbarItem(placement: .topBarTrailing) { Button("Close", systemImage: "xmark") { selectedArticle = nil } } } } } } struct Article: Identifiable, Hashable { let id: String let title: String init(articleTitle: String) { self.id = articleTitle self.title = articleTitle } } First, I'm aware that nesting a TabView inside a NavigationSplitView is frowned upon: Apple seems to prefer NavigationSplitView nested inside a Tab. However, for my app, that leads to a very confusing user experience. Users quickly get lost because they end up with different articles open in different tabs and it doesn't align well with my core distinction between two "modes": article selection mode and article reading mode. When the user is in article selection mode (sidebar view), they can pick between different ways of selecting an article (Explore, Bookmarks, History, Search), which are implemented as "tabs". When they pick an article from any tab they jump into article reading mode (the detail view). Second, I'm using .navigationBarBackButtonHidden(true) to remove the auto back button that pops back to the sidebar view. This button does still work in iOS 26.4, even with the nested TabView. However, I can't use the auto back button because my detail view is actually a WebView with its own back/forward logic and UI. Therefore, I need a separate close button to exit from the detail view. My close button sets selectedArticle to nil, which (pre-iOS 26.4) would trigger the NavigationSplitView to pop back to the sidebar view. For some reason, in iOS 26.4 the NavigationSplitView doesn't seem to bind correctly to the List's selection parameter, specifically when there's a TabView nested between them. Or, rather, it binds, but fails to pop back when selection becomes nil. One option is to replace NavigationSplitView with NavigationStack (on iPhone). NavigationStack still works with a nested TabView, but it creates other downstream issues for me (as well as forcing me to branch for iPhone and iPad), so I'd prefer to continue using NavigationSplitView. Does anyone have any ideas about how to work around this problem? Is there some way of explicitly telling NavigationSplitView to pop back to the sidebar view on iPhone? (I've tried setting the column visibility but nothing seems to work). Thanks for any help!
0
0
49
2w
Localization in Swift macOS console Apps.
Is it possible to build localization into console apps, developed in SwiftUI in Xcode26. I have created a catalog, (.xcstrings file) with an English and fr-CA string. I have tried to display the French text without success. I am using the console app to test a package which also has English/French text. English text works fine in both package and the console main, but I cannot generate the French. From what I can discover so far it's not possible without bundling it as a .app, (console app). Looking for anyone who has crossed this bridge.
7
0
331
2w
Migrating to the UIKit scene-based life cycle
I got this debuglog in Xcode26. "UIScene lifecycle will soon be required. Failure to adopt will result in an assert in the future." I haven't included any UIScene lifecycle code. I read the article on TN3187: Migrating to the UIKit scene-based life cycle. Does this mean that when iOS27 iPhone is released, the app will crash after startup? If Xcode26/iOS27 crashes, is there a quick fix I can use?
Topic: UI Frameworks SubTopic: UIKit
2
0
185
2w
onDisappear not called when closing a document on macOS (Designed for iPad), works on iPad
When running a SwiftUI DocumentGroup app on macOS designed for iPad, onDisappear is not called when closing a document, and deinit of state objects owned by a ContentView is not invoked. This behavior works as expected on iPad. @main struct MyApp: App { var body: some Scene { DocumentGroup(newDocument: MyDocument()) { file in ContentView(document: file.$document) .onDisappear { print("This isn't called on macOS Designed For iPad, but is on iPad when closing a document.") } } } } It is my understanding that for a macOS designed for iPad these lifecycle events would behave the same - otherwise there appears to be no way to detect if a document has closed on macOS.
1
0
91
2w
iPadOS 26 Crash when num pad with floating keyboard in presented view
Build the sample code below, type something in the textfield (make sure the num pad is a popup and that the text keyboard is floating). And tap multiple times outside of the textfield in the sheet. That will lead to the crash: *** Terminating app due to uncaught exception 'NSGenericException', reason: 'Unable to activate constraint with anchors <NSLayoutYAxisAnchor:0x60000179cec0 "UIView:0x103c52fe0.top"> and <NSLayoutYAxisAnchor:0x6000017e0800 "_UIRemoteKeyboardPlaceholderView:0x103baa240.bottom"> because they have no common ancestor. Does the constraint or its anchors reference items in different view hierarchies? That's illegal.' terminating due to uncaught exception of type NSException CoreSimulator 1051.17.8 - Device: iPad Pro 13-inch (M5) (655000D7-41BC-4B13-BD07-BBA80D892E97) - Runtime: iOS 26.2 (23C54) - DeviceType: iPad Pro 13-inch (M5) Does anyone have the slightest idea of a workaround? I can't find one. import SwiftUI struct ContentView: View { var body: some View { Text("Content") .sheet(isPresented: .constant(true)) { PresentedView() } } } struct PresentedView: View { @State private var text = "" var body: some View { ScrollView { VStack { TextField("Placeholder", text: $text) .keyboardType(.numberPad) } .padding(80) } } } See here for discussion and video to reproduce: https://stackoverflow.com/questions/79905933/ipados-26-crash-when-floating-num-pad-in-presented-view
0
1
30
2w
SwiftUI Chart scrolling on macOS
I'm running macOS 26.3 and using Xcode 26.4. I'm trying to create a SwiftUI Chart that can scroll horizontally. In the SwiftUI Preview, and also running the app on macOS, the chart displays a scrollbar, but the scrollbar does not respond to mouse interaction (dragging the scrollbar, or clicking in the gutters on either side of the scrollbar). Here's the sample code: import SwiftUI import Charts private struct DataPoint: Identifiable { let id: Int let x: Double let value: Double } struct ContentView: View { private let points: [DataPoint] = (0..<60).map { index in let wave = sin(Double(index) * 0.28) * 18 let trend = Double(index) * 0.35 return DataPoint(id: index, x: Double(index), value: 60 + wave + trend) } var body: some View { Chart(points) { point in BarMark( x: .value("Data Point", point.x), y: .value("Value", point.value) ) .foregroundStyle(.blue.gradient) } .chartScrollableAxes(.horizontal) // Doesn't work: // .scrollIndicators(.hidden) // .never also does not work .chartXVisibleDomain(length: 20) .padding() } } #Preview { ContentView() }
3
0
142
2w
CPListImageRowItem layout issue with 3 items on iOS < 26 (UI lag when using imageTitles)
Description: I’m using CPListTemplate and creating rows with CPListImageRowItem using the following initializer: if #available(iOS 17.4, *) { self.init(text: titleList, images: imagesRow, imageTitles: titlesRow) } Problem: When displaying 3 items instead of 4, on iOS versions below 26, the items are automatically stretched to fill the available width. This leads to a serious issue: The UI becomes laggy when interacting with the control buttons on the right The interface “jumps” and behaves inconsistently After investigating, I found that: If imageTitles is set to nil, the issue disappears and everything works smoothly Behavior difference: On iOS 26, this issue does not occur Items are no longer stretched when there are only 3 — instead, empty space remains on the right Questions: Is this a known issue or expected behavior on older iOS versions? Is there a recommended workaround besides setting imageTitles = nil?
0
0
89
2w
NSWorkspace - macOS Tahoe 26.4 -activateFileViewerSelectingURLs: Crashes When Called Off The Main Thread
So I just installed the 26.4 update and unfortunately I have to debug this newly introduced issue (that may work its way into a separate thread). In my debugging steps I'm testing something related to files and I used -activateFileViewerSelectingURLs: to show the file in Finder. Now I am off the main thread. I added this line for testing purposes and I get a crash: NSWindow should only be instantiated on the main thread!' terminating due to uncaught exception of type NSException. So apparently - NSWorkspace is calling through to NSServices APIs and for some reason the system wants to present an NSError, which is a subtopic and other bug on its own because the 'Show in Finder" functionality actually WORKS but it crashed my app! #22in +[NSAlert alertWithError:] () #23in -[NSApplication(NSErrorPresentation) presentError:] () #24 +[NSServicesMenuHandler _performServiceFromEntry:withPasteboard:withRequestor:withInvocationSourceType:withCarbonFocus:withSendTypes:withReturnTypes:canReleasePasteboardImmediately:] () #25 +[NSServicesMenuHandler _performServiceWithoutAlternatesFromEntry:withPasteboard:withRequestor:withInvocationSourceType:] () #26 +[NSServicesMenuHandler _performServiceFromEntry:withPasteboard:withRequestor:withInvocationSourceType:] () #27 [NSWorkspace activateFileViewerSelectingURLs:] What error it is trying to present.. I have no idea. I'm not sure if I actually have a code path that calls this method off the main thread but I guess I'll have to check. This clearly goes against the documentation. NSWorkspace documentation clearly states: -activateFileViewerSelectingURLs: Discussion You can safely call this method from any thread of your app. Is this new in 26.4? I'm not sure but I just noticed. I definitely use other NSWorkspace methods off the main thread in areas of my app. Like -activateFileViewerSelectingURLs: the documentation for those other methods claims you can safely call them off the main thread. So now I'm concerned.
3
0
74
2w
NSTextAttachment.character symbol suddenly not available anymore resulting in compiler error
I published the latest update of my AppKit app in September with macOS 26.0. I just wanted to create a new update, but compiling on macOS 26.4 now fails because of the symbol NSTextAttachment.character which is referenced in my code. The error is Type 'NSTextAttachment' has no member 'character' I've never experienced before that a symbol suddenly is not available anymore without even a deprecation notice from one OS release to the next, let alone a minor release. Is this a bug in macOS or Xcode, or should I start worrying about symbols becoming unavailable anytime?
Replies
3
Boosts
0
Views
228
Activity
1w
Potentially Unfair Limitation for Third-Party Keyboard Developers
When developing a custom keyboard on iOS, even after enabling Full Access (RequestsOpenAccess = true), it is still not possible to record audio — the recording simply does not start. This is despite the fact that: the user is explicitly warned the user provides informed consent by enabling Full Access According to Apple’s documentation: https://developer.apple.com/documentation/uikit/configuring-open-access-for-a-custom-keyboard “However, with RequestsOpenAccess set to true, the keyboard has all the capabilities in the preceding list.” At the same time, the preceding list includes: “No access to microphone and speaker” This creates ambiguity. The wording suggests that enabling Full Access should lift prior restrictions, yet in practice, microphone access remains unavailable to third-party keyboards. Why this is concerning With Full Access enabled, a keyboard already has: network access the ability to transmit user input From a privacy standpoint, this is already highly sensitive. Preventing microphone access while allowing these capabilities appears inconsistent. Meanwhile, Apple’s own system keyboard supports voice dictation, which creates a functional gap between first-party and third-party keyboards. Competition perspective This raises a broader question about equal access to platform capabilities. Restricting third-party keyboards from using the microphone — while first-party solutions can — may be seen as: unequal treatment of developers a limitation of competition in input methods Such differences are increasingly scrutinized under EU regulations like the Digital Markets Act and Article 102 TFEU, which emphasize fair access to platform features and prohibit self-preferencing by dominant platforms. Request for clarification Is microphone access intentionally restricted for all third-party keyboards, even with Full Access enabled? If so, what is the technical or policy justification? Are there plans to provide a secure and user-consented way to enable audio input for custom keyboards? Clarification on this would help developers better understand platform limitations and design decisions.
Replies
0
Boosts
0
Views
120
Activity
1w
UITextView cursor sometimes jumps up when pressing arrow down key and setting typingAttributes
My app uses TextKit 1 and unfortunately still cannot migrate to TextKit 2 because of some bugs (for instance in FB17103305 I show how NSTextView.shouldDrawInsertionPoint has no effect, but I opened that feedback exactly one year ago and it still has no answer). Unfortunately TextKit 1 has another bug which causes the text cursor to jump unpredictably up or down when pressing the arrow keys and setting UITextView.typingAttributes. Run the code below on iPhone 17 Pro Max Simulator. Scroll the text down until you see “Header 2”. Place the text cursor after “# “. Press the arrow down key twice to move the cursor two lines down. The cursor moves to the top of the view instead. Continuing to press the arrow keys up and down results in the cursor sometimes moving as expected, other times jumping around wildly. Does anyone know a workaround? I created FB22382453. class TextView: UITextView, UITextViewDelegate { override func awakeFromNib() { let _ = layoutManager delegate = self let header = textAttributes(fontSize: 30) let body = textAttributes(fontSize: 15) let string = NSMutableAttributedString(string: String(repeating: "a", count: 2681) + "\n", attributes: body) string.append(NSAttributedString(string: """ # Header 1 """, attributes: header)) string.append(NSMutableAttributedString(string: String(repeating: "a", count: 5198) + "\n", attributes: body)) string.append(NSAttributedString(string: """ # Header 2 """, attributes: header)) string.append(NSMutableAttributedString(string: String(repeating: "a", count: 7048) + "\n", attributes: body)) textStorage.setAttributedString(string) } func textViewDidChangeSelection(_ textView: UITextView) { typingAttributes = textStorage.attributes(at: selectedRange.location - 1, effectiveRange: nil) } private func textAttributes(fontSize: Double) -> [NSAttributedString.Key: Any] { var textAttributes = [NSAttributedString.Key: Any]() textAttributes[.font] = UIFont(name: "Courier", size: fontSize) let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.minimumLineHeight = round(fontSize * 1.3) paragraphStyle.maximumLineHeight = paragraphStyle.minimumLineHeight textAttributes[.paragraphStyle] = paragraphStyle return textAttributes } }
Topic: UI Frameworks SubTopic: UIKit Tags:
Replies
0
Boosts
0
Views
108
Activity
1w
PDFView left-anchors to window edge instead of centering between sidebar and inspector (macOS Tahoe)
I'm building a document viewer on macOS Tahoe with a 3-column NSSplitViewController (sidebar | detail | inspector), trying to replicate how Preview displays PDFs with the page centered in the visible gap between the panels, with content bleeding under them when panning or zooming. I'm using the approach from Build an AppKit app with the new design (WWDC25): detailItem.automaticallyAdjustsSafeAreaInsets = true safeAreaInsets reports the correct values (e.g. left: 208, right: 240), and the frame does extend under both panels. But PDFView with autoScales = true anchors the page to the left edge of the window instead of centering it in the visible gap between the sidebar and inspector. I can get the page to center correctly by constraining PDFView to view.safeAreaLayoutGuide, but then content no longer extends under the panels when panning or zooming, which defeats the whole purpose. What's the correct way to center PDFView content within the visible gap while keeping the frame full-width so content bleeds under the panels? I've attached pictures of how Preview does it.
Topic: UI Frameworks SubTopic: AppKit
Replies
0
Boosts
0
Views
75
Activity
1w
UIScrollView Fast Scrolling have it scroll to the beginning when i press dpad to left while vertical scrolling
I'm triaging the issue with the fast scrolling on UIScrollView and I'm really upset how little to no info this component is on the internet. Like i disabled scrolling and yet after holding the dpad down to scroll downward eventually the fast scroll mechanism is used. The issue I have is that I have a setup where the scrollview scrolling is disabled and whenever cells are focused it'll scroll to the cell's position for that cells to focused on top left side of the scrollview. I start off with the cell placed at position x of 1000. I scroll down enough to enable fast scrolling. While fast scrolling vertically, i press left a couple of time and it somewhat scroll horizontally. Actual scrollView index is suddenly placed to x:0 instead of let say x:950-1000 Expected should be scrolled to the left of cell at position x 1000. Attached the stack trace and the log showcasing it and run it on simulator tvos 26.2. Initial properties of the scrollview we set up scroll = [UIScrollView new]; scroll.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; scroll.automaticallyAdjustsScrollIndicatorInsets = false; [scroll setDirectionalLockEnabled:TRUE]; [scroll setContentInset:UIEdgeInsetsMake(0, 0, 0, 0)]; scroll.bounces = FALSE; scroll.delaysContentTouches = FALSE; scroll.showsVerticalScrollIndicator = FALSE; scroll.showsHorizontalScrollIndicator = FALSE; The plan for me at least is to somehow disable the horizontal scrolling interaction of it when fast scrolling is enabled, without accessing the private components of it.
Replies
0
Boosts
0
Views
79
Activity
1w
Scene resizing on iPad breaks UIPageViewController's setViewControllers
The following is verbatim of a feedback report (FB22367951) I submitted, shared here as someone else might be interested to see it. I have reproduced this bug on iPadOS 26.3.1 (a) and 26.4. During scene resizing on iPad, UIPageViewController's setViewControllers method fails to do its work. The navigation starts and for a brief moment you can see the new view controller coming from the expected direction, but shortly after it fails and stays on the same [current] view controller. It doesn't even call the completion handler when it fails. When the navigation succeeds (due to not resizing a scene during the navigation) after previously failing at least once, the completion handler is sometimes called more than once. I have created a demo project, which I have pushed to this repo: https://github.com/galijot/SceneResize-Breaks-UIPageViewController I have also attached a zip of the project to this report.
Replies
0
Boosts
0
Views
80
Activity
1w
MapKit in SwiftUI
Anyone worked with MapKit's MapCameraPosition in SwiftUI? I'm building a navigation app and ran into a limitation I can't find a clean solution for when using .userLocation(followsHeading: true) MapKit takes full control of the camera, smooth heading tracking, follows the user automatically. Perfect. But there's no way to set a custom pitch (tilt) on it. The only initializer available is... .userLocation(followsHeading: true, fallback: .automatic) No pitch, no distance parameters.... The workaround I found is setting .camera(MapCamera(..., pitch: 60)) first, waiting 200ms, then switching to .userLocation(followsHeading: true), MapKit inherits the pitch from the rendered camera state before handing off to user tracking.... It works, but it's clearly exploiting an undocumented behaviour in MapKit's state machine rather than a proper API Has anyone found a cleaner way to achieve this? Or is UIViewRepresentable wrapping MKMapView the only proper solution? It would be awesome to have something like this cameraPosition = .userLocation( followsHeading: true, pitch: 60, distance: 800, fallback: .automatic )
Replies
1
Boosts
0
Views
133
Activity
2w
NavigationLink selection in DisclosureGroup not working with .draggable modifier
NavigationLink selection in DisclosureGroup not working with .draggable modifier This was recently also posted here: https://stackoverflow.com/questions/79914290/ I am playing around with a tree data structure with folders and entries.I would like to add dragging of entries and folders between folders, using .draggable and dropDestination. In my current code, dragging works, but selection of entries no longer works, except if I click outside of the Text If I comment out .draggable(subfolder.name) in func FolderRow(), selection works as expected. How can I make sure both selection and drag and drop works for both folders and entries? I also tried using Transferable and Codable, but I get the same result. Here is an MRE: import SwiftData import SwiftUI @Model final class Folder { @Attribute(.unique) var name: String // Parent var parentFolder: Folder? // Child folders @Relationship(deleteRule: .cascade, inverse: \Folder.parentFolder) var subfolders: [Folder] = [] // Leaf entries @Relationship(deleteRule: .cascade, inverse: \Entry.folder) var entries: [Entry] = [] init(name: String, parentFolder: Folder? = nil) { self.name = name self.parentFolder = parentFolder } } @Model final class Entry { @Attribute(.unique) var name: String var detail: String var folder: Folder? // recursive relationship init(name: String, detail: String) { self.name = name self.detail = detail } } @main struct TestMacApp: App { var body: some Scene { WindowGroup { SidebarView() .modelContainer(for: Folder.self) } } } struct SidebarView: View { @Environment(\.modelContext) private var context @Query(filter: #Predicate<Folder> { $0.parentFolder == nil }) private var rootFolders: [Folder] var body: some View { NavigationSplitView { List { ForEach(rootFolders) { folder in FolderRow(folder: folder) .draggable(folder.name) } } } detail: { Text("detail") } .onAppear { seed() } } } struct FolderRow: View { @Environment(\.modelContext) private var context var folder: Folder @State private var isExpanded: Bool = true var body: some View { DisclosureGroup(isExpanded: $isExpanded) { // Subfolders ForEach(folder.subfolders) { subfolder in FolderRow(folder: subfolder) .draggable(subfolder.name) // disabling this line fixes the selection } // Entries (leaf nodes) ForEach(folder.entries) { entry in NavigationLink(destination: EntryDetail(entry: entry)) { EntryRow(entry: entry) } .draggable(entry.name) } } label: { Label(folder.name, systemImage: "folder") } .dropDestination(for: String.self) { names, _ in return handleDrop(of: names) } } } struct EntryRow: View { var entry: Entry var body: some View { Text(entry.name) } } struct EntryDetail: View { var entry: Entry var body: some View { Text(entry.detail) } } extension FolderRow { private func handleDrop(of names: [String]) -> Bool { do { for name in names { if let droppedEntry = try context.fetchFilteredModel(filter: #Predicate<Entry> { x in x.name == name }) { droppedEntry.folder = folder print("dropped \(droppedEntry.name) on \(folder.name)") } else if let droppedFolder = try context.fetchFilteredModel(filter: #Predicate<Folder> { x in x.name == name }) { if droppedFolder.parentFolder != nil && droppedFolder != folder { droppedFolder.parentFolder = folder print("dropped \(droppedFolder.name) on \(folder.name)") } } } return true } catch { debugPrint(error.localizedDescription) return false } } } extension SidebarView { private func seed() { do { // delete current models for folder: Folder in try context.fetchAllModels() { context.delete(folder) } try context.save() let rootFolder = Folder(name: "Root") let entry1 = Entry(name: "One", detail: "Detail One") let entry2 = Entry(name: "Two", detail: "Detail Two") rootFolder.entries.append(contentsOf: [entry1, entry2]) let subFolder1 = Folder(name: "Sub1", parentFolder: rootFolder) let entry3 = Entry(name: "Three", detail: "Detail Three") let entry4 = Entry(name: "Four", detail: "Detail Four") subFolder1.entries.append(contentsOf: [entry3, entry4]) let subFolder2 = Folder(name: "Sub2", parentFolder: rootFolder) let entry5 = Entry(name: "Five", detail: "Detail Five") let entry6 = Entry(name: "Six", detail: "Detail Six") subFolder2.entries.append(contentsOf: [entry5, entry6]) context.insert(rootFolder) } catch { debugPrint(error) } } } extension ModelContext { // convenience methods func fetchAllModels<M>() throws -> [M] where M: PersistentModel { let fetchDescriptor = FetchDescriptor<M>() return try fetch(fetchDescriptor) } func fetchFilteredModels<M>(filter: Predicate<M>) throws -> [M] where M: PersistentModel { let fetchDescriptor = FetchDescriptor<M>(predicate: filter) return try fetch(fetchDescriptor) } func fetchFilteredModel<M>(filter: Predicate<M>) throws -> M? where M: PersistentModel { return try fetchFilteredModels(filter: filter).first } }
Topic: UI Frameworks SubTopic: SwiftUI
Replies
1
Boosts
0
Views
188
Activity
2w
Left navigation bar items become invisible after rotating device and presenting detail view in split view
A user of my app, whose main view is a split view, reported an issue which causes the left navigation bar items to disappear without apparent reason if they rotate the device and later show the detail view, preventing them from using the back button to show the root view again. Am I doing something wrong or is it a bug? I can reproduce the issue with the following steps: Create a new document-based iOS app (as it uses scenes by default, as opposed to a regular app). Paste the code below. In the target build settings, delete "Launch Screen Interface File Base Name" and set "Launch Screen (Generation)" to YES. Without this step, for some reason, the issue doesn't happen. Launch the app in iPhone Simulator. Tap the top left button to show the root view, then the “detail” button to show the detail view. The left navigation bar button is still visible. Rotate the Simulator window right, then left again. Tap the top left button to show the root view, then the “detail” button to show the detail view. Now the left navigation bar button is invisible. Rotating the device right and left again solves the issue. I filed FB22363118. class SceneDelegate: UIResponder, UIWindowSceneDelegate { var window: UIWindow? func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { window = UIWindow(windowScene: scene as! UIWindowScene) let split = SplitViewController() window!.rootViewController = split window!.makeKeyAndVisible() split.showDetail() } } class SplitViewController: UISplitViewController, UISplitViewControllerDelegate { var detailNavigationViewController: UINavigationController! init() { super.init(nibName: nil, bundle: nil) detailNavigationViewController = UINavigationController(rootViewController: DetailViewController()) viewControllers = [UINavigationController(rootViewController: RootViewController())] } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } func showDetail() { showDetailViewController(detailNavigationViewController, sender: nil) } func showRoot() { (viewControllers.first as? UINavigationController)?.popViewController(animated: true) } } class RootViewController: UIViewController { override func loadView() { navigationItem.title = "root" let button = UIButton(primaryAction: UIAction(handler: { [self] _ in (splitViewController as! SplitViewController).showDetail() })) button.setTitle("detail", for: .normal) view = button } } class DetailViewController: UIViewController { override func loadView() { navigationItem.title = "detail" view = UIView() registerForTraitChanges([UITraitHorizontalSizeClass.self]) { (self: Self, previousTraitCollection) in if previousTraitCollection.horizontalSizeClass != self.traitCollection.horizontalSizeClass { self.updateBarButtons() } } updateBarButtons() } private func updateBarButtons() { navigationItem.leftBarButtonItem = UIBarButtonItem(primaryAction: UIAction(image: UIImage(systemName: "sidebar.leading")) { [self] _ in (self.splitViewController as! SplitViewController).showRoot() }) navigationItem.rightBarButtonItem = UIBarButtonItem(title: "right") } }
Topic: UI Frameworks SubTopic: UIKit Tags:
Replies
0
Boosts
0
Views
67
Activity
2w
How to recreate Apple Music mini player transition in SwiftUI
Hello, I am building an audio player app in SwiftUI and trying to recreate the behavior of Apple Music's mini player and full player. I'm struggling to get the animation to seamlessly transition between the mini player and the full player. Currently, it feels disconnected and doesn't resemble the smooth animation seen in Apple Music. What I want to achieve: Full player that expands/collapses from/to the mini player Smooth artwork transition between both states Drag down to collapse the full player Support both newer APIs like tabViewBottomAccessory and older iOS versions Questions: What is the best way to build this transition in SwiftUI? Should I use matchedGeometryEffect or something else? Should this be a custom container instead of fullScreenCover? How would you support both new and older iOS versions? What is the best way to implement drag to dismiss? Thanks for any help! Example code: struct ContentView: View { @State private var isFullPlayerPresented = false var body: some View { TabView { Tab("Home", systemImage: "house") { Text("Home") .frame(maxWidth: .infinity, maxHeight: .infinity) .background(.green) } Tab("Library", systemImage: "rectangle.stack.fill") { Text("Library") .frame(maxWidth: .infinity, maxHeight: .infinity) .background(.brown) } } .tabViewBottomAccessory(isEnabled: !isFullPlayerPresented) { MiniPlayerView(isFullPlayerPresented: $isFullPlayerPresented) } .fullScreenCover(isPresented: $isFullPlayerPresented) { // Maybe it's not a full screen cover presentation in Apple Music? FullPlayerView(isFullPlayerPresented: $isFullPlayerPresented) } } } Mini player: struct MiniPlayerView: View { @Binding var isFullPlayerPresented: Bool var body: some View { Button { isFullPlayerPresented = true } label: { HStack { Image(systemName: "photo") .resizable() .scaledToFit() .frame(width: 30, height: 30) .clipShape(.rect(cornerRadius: 8)) Spacer() Text("Tap to open full player") Spacer() Button("", systemImage: "play.fill", action: {}) } .padding(.horizontal) .padding(.vertical, 4) } .foregroundStyle(.white) } } Full player: struct FullPlayerView: View { @Binding var isFullPlayerPresented: Bool var body: some View { // This art work needs to snaps to the artwork in mini player Image(systemName: "photo") .resizable() .scaledToFit() .frame(width: 250, height: 250) .clipShape(.rect(cornerRadius: 20)) .frame(maxWidth: .infinity, maxHeight: .infinity) .background(.red) .overlay(alignment: .topTrailing) { Button(role: .close) { isFullPlayerPresented = false } .foregroundStyle(.white) .padding() } } }
Replies
2
Boosts
0
Views
275
Activity
2w
NSBrowser -deselectAll: broken on macOS Tahoe 26.4
So if I have a selection in NSBrowser. I hit Option+Command+A to invoke "Deselect" the selection in the parent for the last column drops its selections, as expected. But the column doesn't drop off the browser. The delegate method (void)browser:(NSBrowser *)browser didChangeLastColumn:(NSInteger)oldLastColumn toColumn:(NSInteger)column NS_SWIFT_UI_ACTOR; Never fires (since the column isn't dropped off). But we have. dangling last column with no selection in the previous column. Now if there's enough room for me to deselect by clicking the background, the last column drops off, as expected. This seems to be fairly new? Anyone else experiencing this? These 26point updates seem to keep punching me in the face. And yes. deselect all seems somewhat broken in Column view in the Finder as well, but in a seemingly different way. In Finder it just seems to change the selection color like it deactivated the window but doesn't drop the selection. For me, the selection IS dropped but the column remains visible. Maybe they are using Cocoa bindings or something that resyncs the selection after the mess up. I dk.
Replies
0
Boosts
0
Views
133
Activity
2w
NavigationSplitView no longer pops back to the root view when selection = nil in iOS 26.4 (with a nested TabView)
In iOS 26.4 (iPhone, not iPad), when a NavigationSplitView is combined with a nested TabView, it no longer pops back to the root sidebar view when the List selection is set to nil. This has been working fine for at least a few years, but has just stopped working in iOS 26.4. Here's a minimal working example: import SwiftUI struct ContentView: View { @State var articles: [Article] = [Article(articleTitle: "Dog"), Article(articleTitle: "Cat"), Article(articleTitle: "Mouse")] @State private var selectedArticle: Article? = nil var body: some View { NavigationSplitView { TabView { Tab { List(articles, selection: $selectedArticle) { article in Button { selectedArticle = article } label: { Text(article.title) } } } label: { Label("Explore", systemImage: "binoculars") } } } detail: { Group { if let selectedArticle { Text(selectedArticle.title) } else { Text("No selected article") } } .navigationBarBackButtonHidden(true) .toolbar { ToolbarItem(placement: .topBarTrailing) { Button("Close", systemImage: "xmark") { selectedArticle = nil } } } } } } struct Article: Identifiable, Hashable { let id: String let title: String init(articleTitle: String) { self.id = articleTitle self.title = articleTitle } } First, I'm aware that nesting a TabView inside a NavigationSplitView is frowned upon: Apple seems to prefer NavigationSplitView nested inside a Tab. However, for my app, that leads to a very confusing user experience. Users quickly get lost because they end up with different articles open in different tabs and it doesn't align well with my core distinction between two "modes": article selection mode and article reading mode. When the user is in article selection mode (sidebar view), they can pick between different ways of selecting an article (Explore, Bookmarks, History, Search), which are implemented as "tabs". When they pick an article from any tab they jump into article reading mode (the detail view). Second, I'm using .navigationBarBackButtonHidden(true) to remove the auto back button that pops back to the sidebar view. This button does still work in iOS 26.4, even with the nested TabView. However, I can't use the auto back button because my detail view is actually a WebView with its own back/forward logic and UI. Therefore, I need a separate close button to exit from the detail view. My close button sets selectedArticle to nil, which (pre-iOS 26.4) would trigger the NavigationSplitView to pop back to the sidebar view. For some reason, in iOS 26.4 the NavigationSplitView doesn't seem to bind correctly to the List's selection parameter, specifically when there's a TabView nested between them. Or, rather, it binds, but fails to pop back when selection becomes nil. One option is to replace NavigationSplitView with NavigationStack (on iPhone). NavigationStack still works with a nested TabView, but it creates other downstream issues for me (as well as forcing me to branch for iPhone and iPad), so I'd prefer to continue using NavigationSplitView. Does anyone have any ideas about how to work around this problem? Is there some way of explicitly telling NavigationSplitView to pop back to the sidebar view on iPhone? (I've tried setting the column visibility but nothing seems to work). Thanks for any help!
Replies
0
Boosts
0
Views
49
Activity
2w
Localization in Swift macOS console Apps.
Is it possible to build localization into console apps, developed in SwiftUI in Xcode26. I have created a catalog, (.xcstrings file) with an English and fr-CA string. I have tried to display the French text without success. I am using the console app to test a package which also has English/French text. English text works fine in both package and the console main, but I cannot generate the French. From what I can discover so far it's not possible without bundling it as a .app, (console app). Looking for anyone who has crossed this bridge.
Replies
7
Boosts
0
Views
331
Activity
2w
Migrating to the UIKit scene-based life cycle
I got this debuglog in Xcode26. "UIScene lifecycle will soon be required. Failure to adopt will result in an assert in the future." I haven't included any UIScene lifecycle code. I read the article on TN3187: Migrating to the UIKit scene-based life cycle. Does this mean that when iOS27 iPhone is released, the app will crash after startup? If Xcode26/iOS27 crashes, is there a quick fix I can use?
Topic: UI Frameworks SubTopic: UIKit
Replies
2
Boosts
0
Views
185
Activity
2w
onDisappear not called when closing a document on macOS (Designed for iPad), works on iPad
When running a SwiftUI DocumentGroup app on macOS designed for iPad, onDisappear is not called when closing a document, and deinit of state objects owned by a ContentView is not invoked. This behavior works as expected on iPad. @main struct MyApp: App { var body: some Scene { DocumentGroup(newDocument: MyDocument()) { file in ContentView(document: file.$document) .onDisappear { print("This isn't called on macOS Designed For iPad, but is on iPad when closing a document.") } } } } It is my understanding that for a macOS designed for iPad these lifecycle events would behave the same - otherwise there appears to be no way to detect if a document has closed on macOS.
Replies
1
Boosts
0
Views
91
Activity
2w
iPadOS 26 Crash when num pad with floating keyboard in presented view
Build the sample code below, type something in the textfield (make sure the num pad is a popup and that the text keyboard is floating). And tap multiple times outside of the textfield in the sheet. That will lead to the crash: *** Terminating app due to uncaught exception 'NSGenericException', reason: 'Unable to activate constraint with anchors <NSLayoutYAxisAnchor:0x60000179cec0 "UIView:0x103c52fe0.top"> and <NSLayoutYAxisAnchor:0x6000017e0800 "_UIRemoteKeyboardPlaceholderView:0x103baa240.bottom"> because they have no common ancestor. Does the constraint or its anchors reference items in different view hierarchies? That's illegal.' terminating due to uncaught exception of type NSException CoreSimulator 1051.17.8 - Device: iPad Pro 13-inch (M5) (655000D7-41BC-4B13-BD07-BBA80D892E97) - Runtime: iOS 26.2 (23C54) - DeviceType: iPad Pro 13-inch (M5) Does anyone have the slightest idea of a workaround? I can't find one. import SwiftUI struct ContentView: View { var body: some View { Text("Content") .sheet(isPresented: .constant(true)) { PresentedView() } } } struct PresentedView: View { @State private var text = "" var body: some View { ScrollView { VStack { TextField("Placeholder", text: $text) .keyboardType(.numberPad) } .padding(80) } } } See here for discussion and video to reproduce: https://stackoverflow.com/questions/79905933/ipados-26-crash-when-floating-num-pad-in-presented-view
Replies
0
Boosts
1
Views
30
Activity
2w
SwiftUI Chart scrolling on macOS
I'm running macOS 26.3 and using Xcode 26.4. I'm trying to create a SwiftUI Chart that can scroll horizontally. In the SwiftUI Preview, and also running the app on macOS, the chart displays a scrollbar, but the scrollbar does not respond to mouse interaction (dragging the scrollbar, or clicking in the gutters on either side of the scrollbar). Here's the sample code: import SwiftUI import Charts private struct DataPoint: Identifiable { let id: Int let x: Double let value: Double } struct ContentView: View { private let points: [DataPoint] = (0..<60).map { index in let wave = sin(Double(index) * 0.28) * 18 let trend = Double(index) * 0.35 return DataPoint(id: index, x: Double(index), value: 60 + wave + trend) } var body: some View { Chart(points) { point in BarMark( x: .value("Data Point", point.x), y: .value("Value", point.value) ) .foregroundStyle(.blue.gradient) } .chartScrollableAxes(.horizontal) // Doesn't work: // .scrollIndicators(.hidden) // .never also does not work .chartXVisibleDomain(length: 20) .padding() } } #Preview { ContentView() }
Replies
3
Boosts
0
Views
142
Activity
2w
CPListImageRowItem layout issue with 3 items on iOS < 26 (UI lag when using imageTitles)
Description: I’m using CPListTemplate and creating rows with CPListImageRowItem using the following initializer: if #available(iOS 17.4, *) { self.init(text: titleList, images: imagesRow, imageTitles: titlesRow) } Problem: When displaying 3 items instead of 4, on iOS versions below 26, the items are automatically stretched to fill the available width. This leads to a serious issue: The UI becomes laggy when interacting with the control buttons on the right The interface “jumps” and behaves inconsistently After investigating, I found that: If imageTitles is set to nil, the issue disappears and everything works smoothly Behavior difference: On iOS 26, this issue does not occur Items are no longer stretched when there are only 3 — instead, empty space remains on the right Questions: Is this a known issue or expected behavior on older iOS versions? Is there a recommended workaround besides setting imageTitles = nil?
Replies
0
Boosts
0
Views
89
Activity
2w
QLThumbnailGenerator macOS 26.4 No Longer Honors Users 'Folder Color' Preference When Making Icons for Folders
I use QLThumbnailGenerator to generate icons. After updating to macOS Tahoe 26.4 the folder color preference of the user is no longer respected. It just makes the icon default 'light blue.'
Replies
6
Boosts
0
Views
184
Activity
2w
NSWorkspace - macOS Tahoe 26.4 -activateFileViewerSelectingURLs: Crashes When Called Off The Main Thread
So I just installed the 26.4 update and unfortunately I have to debug this newly introduced issue (that may work its way into a separate thread). In my debugging steps I'm testing something related to files and I used -activateFileViewerSelectingURLs: to show the file in Finder. Now I am off the main thread. I added this line for testing purposes and I get a crash: NSWindow should only be instantiated on the main thread!' terminating due to uncaught exception of type NSException. So apparently - NSWorkspace is calling through to NSServices APIs and for some reason the system wants to present an NSError, which is a subtopic and other bug on its own because the 'Show in Finder" functionality actually WORKS but it crashed my app! #22in +[NSAlert alertWithError:] () #23in -[NSApplication(NSErrorPresentation) presentError:] () #24 +[NSServicesMenuHandler _performServiceFromEntry:withPasteboard:withRequestor:withInvocationSourceType:withCarbonFocus:withSendTypes:withReturnTypes:canReleasePasteboardImmediately:] () #25 +[NSServicesMenuHandler _performServiceWithoutAlternatesFromEntry:withPasteboard:withRequestor:withInvocationSourceType:] () #26 +[NSServicesMenuHandler _performServiceFromEntry:withPasteboard:withRequestor:withInvocationSourceType:] () #27 [NSWorkspace activateFileViewerSelectingURLs:] What error it is trying to present.. I have no idea. I'm not sure if I actually have a code path that calls this method off the main thread but I guess I'll have to check. This clearly goes against the documentation. NSWorkspace documentation clearly states: -activateFileViewerSelectingURLs: Discussion You can safely call this method from any thread of your app. Is this new in 26.4? I'm not sure but I just noticed. I definitely use other NSWorkspace methods off the main thread in areas of my app. Like -activateFileViewerSelectingURLs: the documentation for those other methods claims you can safely call them off the main thread. So now I'm concerned.
Replies
3
Boosts
0
Views
74
Activity
2w