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

sandbox causes the input method switch to fail to take effect
Dear Apple developers: Hello, recently I want to develop an application for macos that automatically switches input methods. The function is that when you switch applications, it can automatically switch to the input method you set, thus eliminating the trouble of manual switching. All the functions have been implemented, but only when the sandbox is closed. When I opened the sandbox, I found a very strange phenomenon. Suppose wechat was set to the Chinese input method. When I switched to wechat, wechat automatically got the focus of the input box. The input method icon in the upper right corner of the screen had actually switched successfully, but when I actually input, it was still the previous input method. If you switch to an application that does not have a built-in focus, the automatic switching of the input method will take effect when you click the input box with the mouse to regain the focus. This phenomenon is too difficult for my current technical level. I have tried many methods but none of them worked. I hope the respected experts can offer some ideas. Below is a snippet of the code switching I provided: DispatchQueue. Main. AsyncAfter (deadline: now () + 0.1) { let result = TISSelectInputSource(inputSource) if result == noErr { print(" Successfully switched to input method: \(targetInputMethod)") } else { print(" Input method switch failed. Error code: \(result)") } // Verify the switching result if let newInputSource = getCurrentInputSource() { print(" Switched input method: (newInputSource)") } } When the sandbox is opened, the synchronous switching does not take effect. The input method icon in the status bar will flash for a moment, unable to compete with system events. Even if it is set to DispatchQueue.main.async, it still does not work. It seems that there is a timing issue with the input method switching. Development environment macOS version: 15.4.1 Xcode version: 16.2
0
0
194
Jul ’25
Debug an issue with NSWindow becoming narrow
For months now we're trying to find an issue with one of our apps, were a window suddenly becomes narrow and can't be resized horizontally any more. It's a bug that only happens sporadically and we can't provide a "focused test project" to demonstrate the issue; thus we can't ask for code-level support at this moment. To debug this issue, we've overwritten a private method on NSWindow that gets the constrained window min and max sizes (valuable hint of Kristin from the AppKit team in a WWDC 2025 one-on-one session where I was able to show it to her in my debugger). When the bug hits, the maxSize's width (usually 10000) becomes smaller than the minSize's width. One way (but not the only one) to trigger this issue is to move the window from one display to another and back. Sometimes the bug triggers after a few back-and-forth movements, sometimes it takes minutes to trigger or I give up… but for other people the bug happens seemingly out of nowhere (of course there must be a trigger but we haven't noticed common patterns yet). It looks like an AutoLayout issue since a suspicious thing happens when the bug triggers: calling constraintsAffectingLayoutForOrientation:NSLayoutConstraintOrientationHorizontal on the NSThemeFrame usually returns just two constraints. But when the bug triggers, it returns a whole bunch of constraints, related to all kind of views of our app. Asking the NSThemeFrame for its direct constraints still shows the same two constraints are present and active (NSWindow-current-width and NSWindow-x-anchor). How to proceed in hunting down this issue when we're unable to produce a demo project? We can only reproduce the bug with our big product, and only sporadically: sometimes I can trigger it in a minute, sometimes it takes me 15 minutes or even more. Issue happens on macOS 15 (currently running 15.5).
1
0
168
Jul ’25
Glass effect on a stroke
I'm trying to apply a glass effect on a circle stroke but all it does is apply it to the circle itself and not the stroke: import SwiftUI let kCarouselCircleSize: CGFloat = 150 let kCarouselOpacity: Double = 0.3 let kCarouselStrokeWidth: CGFloat = 60 struct ContentView: View { @State var showing = false var body: some View { VStack(spacing: 60) { Text("ultraThinMaterial:") .font(.title) CarouseCircle(drawProgress: 0.7, isActive: false) Text("glassEffect()") .font(.title) CarouseCircle(useGlassEffect: true, drawProgress: 0.7, isActive: false) } .background(content: { Image(.background2) }) .padding() } } struct CarouseCircle: View { var size: CGFloat = kCarouselCircleSize var strokeWidth: CGFloat = kCarouselStrokeWidth var useGlassEffect: Bool = false var drawProgress: CGFloat var isActive: Bool var body: some View { if useGlassEffect { Circle() .trim(from: 0, to: drawProgress) .fill(.clear) .stroke(.blue, style: StrokeStyle(lineWidth: strokeWidth, lineCap: .round)) .frame(width: size, height: size) .glassEffect() .shadow(color: .black.opacity(kCarouselOpacity), radius: isActive ? 4 : 1, x: 0, y: 0) .rotationEffect(.degrees(-90)) // Start drawing at button 1's position } else { Circle() .trim(from: 0, to: drawProgress) .fill(.clear) .stroke(.ultraThinMaterial, style: StrokeStyle(lineWidth: strokeWidth, lineCap: .round)) .frame(width: size, height: size) .shadow(color: .black.opacity(kCarouselOpacity), radius: isActive ? 4 : 1, x: 0, y: 0) .rotationEffect(.degrees(-90)) // Start drawing at button 1's position } } } Here's the result: Is this supported, a bug or something I'm doing wrong?
Topic: UI Frameworks SubTopic: SwiftUI Tags:
0
0
186
Jul ’25
Crash due to likely infinitely recursive call in SwiftUI `Color.Resolved.init`
So I'm dealing with a really obtuse crash that appears to be a stack overflow in an internal SwiftUI code path creating a Color.Resolved. I haven't found anyone one else with this issue online, and I cannot get it to reproduce on my own device. Interestingly enough, it is only happening on 1 device in the field (according to XCode crash logs). Here are some lines from the crashed thread. You can see that my code is never called, and it appears to be starting in some Array equality check checking the equality of colors (which I can't think of anywhere in my app I am doing anyway). You can see from this trace here that it appears to be a recursive call through Color.Resolved and NSColor.withColorAppearance. I don't have any idea how to solve this, but it keeps happening with at least one in-the-field device across multiple app updates. So my whole app is open source on github at https://github.com/msdrigg/roam, but I don't even use NSColor explicitly anywhere except for here which doesn't match the stack trace. I also tried changing the accent color of the app with defaults write com.msdrigg.roam AppleAccentColor -integer 1 to see if that somehow caused the crash, but my app opened up totally fine (and respected the change). Besides this, the only places I think I could be using dynamic colors is I when define an AccentColor and a WidgetBackground color for my app using xcassets, and then I use these colors from SwiftUI. In most of my app I stick to the system colors (Color.gray and such). Thread 0 Crashed: 0 libsystem_pthread.dylib 0x000000018601213c ___chkstk_darwin + 60 1 CoreFoundation 0x0000000186108434 -[NSArray isEqualToArray:] + 52 (NSArray.m:454) 2 AppKit 0x000000018a21fcd4 -[NSCoreUICatalogColor resolvedCUINamedColorForAppearance:] + 164 (NSColor.m:5057) 3 AppKit 0x0000000189c32cd4 -[NSCoreUICatalogColor resolvedColor] + 48 (NSColor.m:5148) 4 AppKit 0x0000000189c31e74 -[NSDynamicNamedColor colorUsingColorSpace:] + 32 (NSColor.m:4410) 5 SwiftUICore 0x0000000221ca9fd8 CoreColorPlatformColorGetComponents + 116 (CoreColorFunctions.m:149) 6 SwiftUICore 0x0000000221faaf28 specialized Color.Resolved.init(platformColor:) + 92 (CoreColor.swift:14) 7 SwiftUICore 0x0000000221faa5b0 Color.Resolved.init(platformColor:) + 16 (<compiler-generated>:0) 8 SwiftUI 0x00000001b53b1dc4 closure #1 in NSColor.resolve(in:) + 20 (AppKitColorConversions.swift:156) 9 SwiftUI 0x00000001b53b222c partial apply for closure #1 in static NSColor.withColorAppearance(in:_:) + 32 (<compiler-generated>:0) 10 SwiftUI 0x00000001b46b1e54 closure #1 in SubmitTriggerSource.dispatchUpdate(_:) + 28 (PlatformViewCoordinator.swift:12) 11 SwiftUI 0x00000001b5484488 thunk for @escaping @callee_guaranteed () -> () + 28 (<compiler-generated>:0) 12 AppKit 0x0000000189c174a4 +[NSAppearance _performWithCurrentAppearance:usingBlock:] + 72 (NSAppearance.m:2408) 13 SwiftUI 0x00000001b53b2088 specialized static NSColor.withColorAppearance(in:_:) + 324 (AppKitColorConversions.swift:142) 14 SwiftUI 0x00000001b53b1e7c protocol witness for ColorProvider.resolve(in:) in conformance NSColor + 68 (<compiler-generated>:151) 15 SwiftUICore 0x0000000222436e6c ColorBox.resolve(in:) + 124 (Color.swift:288) 16 SwiftUICore 0x0000000222435e30 Color.resolve(in:) + 72 (Color.swift:87) 17 SwiftUI 0x00000001b53b1c88 closure #1 in NSColor.init(_:) + 196 (AppKitColorConversions.swift:124) 18 SwiftUI 0x00000001b4542714 thunk for @escaping @callee_guaranteed (@guaranteed NSAppearance) -> (@owned NSColor) + 56 (<compiler-generated>:0) 19 AppKit 0x0000000189c31e74 -[NSDynamicNamedColor colorUsingColorSpace:] + 32 (NSColor.m:4410) //// ... Repeating for 500 lines 500 SwiftUICore 0x0000000221ca9fd8 CoreColorPlatformColorGetComponents + 116 (CoreColorFunctions.m:149) 501 SwiftUICore 0x0000000221faaf28 specialized Color.Resolved.init(platformColor:) + 92 (CoreColor.swift:14) 502 SwiftUICore 0x0000000221faa5b0 Color.Resolved.init(platformColor:) + 16 (<compiler-generated>:0) 503 SwiftUI 0x00000001b53b1dc4 closure #1 in NSColor.resolve(in:) + 20 (AppKitColorConversions.swift:156) 504 SwiftUI 0x00000001b53b222c partial apply for closure #1 in static NSColor.withColorAppearance(in:_:) + 32 (<compiler-generated>:0) 505 SwiftUI 0x00000001b46b1e54 closure #1 in SubmitTriggerSource.dispatchUpdate(_:) + 28 (PlatformViewCoordinator.swift:12) 506 SwiftUI 0x00000001b5484488 thunk for @escaping @callee_guaranteed () -> () + 28 (<compiler-generated>:0) 507 AppKit 0x0000000189c174a4 +[NSAppearance _performWithCurrentAppearance:usingBlock:] + 72 (NSAppearance.m:2408) 508 SwiftUI 0x00000001b53b2088 specialized static NSColor.withColorAppearance(in:_:) + 324 (AppKitColorConversions.swift:142) 509 SwiftUI 0x00000001b53b1e7c protocol witness for ColorProvider.resolve(in:) in conformance NSColor + 68 (<compiler-generated>:151) 510 SwiftUICore 0x0000000222436e6c ColorBox.resolve(in:) + 124 (Color.swift:288) full-log.crash
0
0
146
May ’25
How to sync stroke between two PKCanvasViews with one in a UIScrollView with scale not 1
I got 3 PKCanvasView, 2 below the Major one. Users draw lines on the top one, then sync the last stroke to the one underneath. If the stroke crosses two PKCanvasView, we replace the stroke with a bezier curve. If a stroke doesn't cross regions, we sync the stroke to the one below it(B) as if it is drawn directly on B. The problem is if the B is inside a UIScrollview with a zoom scale not 1, the stroke from major to B will shrink or grow. Does anybody have a solution for this please? What I did Also put the major canvas into a uiScrollview, and make sure the zoomScale is the same as the B. for scale >=1, it works as expected, for scale < 1, sometimes it works, sometimes it doesn't. for example, 0.5, 0.6, 0.8, 0.5 doesn't work, 0.6, 0.8 works, I don't know why. What it costs It cost me 16*4 hours for these days. I didn't find a solution. Hopefully, some one can solve it.
0
0
252
Jul ’25
Mixing ReferenceFileDocument and @Observable
I have an app in which the data model is @Observable, and views see it through @Environment(dataModel.self) private var dataModel. Since there are a large number of views, only some of which may need to be redrawn at a given time, I believe that @Observable is more efficient at run time than @Published and @ObservedObject I’ve been trying to make the app document based. Although I started using SwiftData, it has trouble with Codable, and a long thread in the Developer forum suggests that SwiftData does not support the Undo manager - and in any event, simple JSON serialization is all that this app requires. Unfortunately, ReferenceFileDocument inherits from ObservableObject, which seems to not play nice with @Observable. I’d like to keep using @Observable, but haven’t been able to figure out how. When I deserialize a JSON ReferenceFileDocument, I can’t seem to connect it to an @Observable class instance and to let the various views and view models know where to find and update it. I’d appreciate advice on how to implement document persistence in this app. Also, the default behaviour of DoumentGroup provides a nice menu to, another things, rename a new file to something other than Untitled xx, but it doesn’t appear to work (there is an extensive thread on the Developer website discussing this issue). Is there a solution to this problem? Thanks for any help you can offer.
3
0
177
May ’25
Resolving AppIntent in the app from a widget...
Is anyone familiar with AppIntents and their usage? I have an AppIntent defined in my widget extension. I have the same AppIntent defined in the app marked as ForegroundContinuableIntent. If I add the intent on a SwiftUI button and tap the Button it correctly resolves the app's version of the intent and performs that intent. However, what I really want to do is perform the AppIntent manually as the timeline updates but not more often than every hour (i.e. >= 1 hour). It's easy enough to handle the timing in the timeline. However, I do not know how to resolve the intent such that it calls the app's version of the intent (i.e. the same way that a Button does). If I just call perform it will run the version in the widget extension. The end goal is to minimally / periodically sync with the app. Thanks in advance for any help / advice on this.
Topic: UI Frameworks SubTopic: SwiftUI
3
0
151
Jun ’25
Window number too large
I'm trying to get information about my status items window. I get the window number using this call: statusItem.button?.window?.windowNumber With that number I try to determine if it visible or not. On macOS 15, this works fine, however on macOS Tahoe the window number is bigger than UInt32 or its type alias CGWindowID, causing a crash of my app (when converting from Int to UInt32). Somehow the window numbers were always in the 32-bit space. I can only guess about the reasons for increase of the window number beyond the UInt32 bounds. I don't know how the windows are numbered, but something may not be going as expected here. Anyone knows if this may be due to running in a virtual machine?
Topic: UI Frameworks SubTopic: General Tags:
1
0
107
Jun ’25
SwiftUI: scrollEdgeEffectStyle(.hard, for: .all) bug with preferredColorScheme(.dark)
In the small example below, I have set .preferredColorScheme(.dark). I am pushing a view that has a List. I have a custom background color. When .scrollEdgeEffectStyle(.hard, for: .all) is used, the pushed view top and bottom safe areas flash black before being replaced by the blue background color. If I change this to .scrollEdgeEffectStyle(.soft, for: .all), the issue goes away. If I do not set preferredColorScheme(.dark), the issue also goes away. I filled FB18465023, but wonder if I am just doing something wrong? Video of sample running: https://www.youtube.com/shorts/87rWqHtdmKw. var body: some View { NavigationStack { VStack { Image(systemName: "globe") .imageScale(.large) .foregroundStyle(.tint) Text("Hello, world!") NavigationLink("Push New View") { PushedView() } .buttonStyle(.glass) .padding() } .frame(maxWidth: .infinity, maxHeight: .infinity) .ignoresSafeArea(.all) .background(.blue) } .preferredColorScheme(.dark) } } struct PushedView: View { @State private var searchText = "" var body: some View { List { ForEach(1...30, id: \.self) { index in Label("Label \(index)", systemImage: "number.circle") .listRowBackground(Color.blue) } } // This causes the top and bottom safe areas to start off black before // getting the blue background from below .scrollEdgeEffectStyle(.hard, for: .all) // This does not have the issue // .scrollEdgeEffectStyle(.hard, for: .all) .listStyle(.plain) .background(.blue) .searchable(text: $searchText, prompt: "Search labels...") .toolbar { ToolbarItem(placement: .topBarTrailing) { Button("Toolbar Button", systemImage: "questionmark") { print("touched") } } } } }
Topic: UI Frameworks SubTopic: SwiftUI
1
0
295
Jul ’25
The URL authorization read and write obtained by UIDocumentPickerViewController
The URL directory obtained by UIDocumentPickerVieweController can be read and written in the directory after calling startAccessingDecurityScopeResource. However, after restarting the app, if the URL saved in the package is called startAccessingDecurityScopeResource again and returns NO, UIDocumentPickerVieweController must be called again to retrieve the URL, and then startAccessingDecurityScopeResource must be called again before continuing the operation. This is too troublesome. Is there a way to continue reading and writing operations in the URL directory after restarting the app?
1
0
84
May ’25
Displaying an editing hierarchy in macOS
The SwiftUI Navigation structures work in ways that are not intuitive to me. For example, I am trying to display a set of data that represents rankings contained in a balloting system that I have created. The ballots all have candidates that are ranked from highest preference to lowest. Normally, I try to work backwards in SwiftUI, so I built the ballot editor to take a binding to the ballot itself: struct BallotEditor: View { @Binding var ballot: Election.Ballot var maxRank: Int var body: some View { VStack { ForEach($ballot.rankings) { $ranking in CandidateRankingPicker(maxRanking: maxRank, ranking: $ranking) } } } } This is embedded into a view with a list of ballots: struct BallotsView: View { @Binding var document: ElectionDocument var body: some View { List($document.ballots) { $ballot in NavigationLink { BallotEditor(ballot: $ballot, maxRank: document.election.candidates.count) .padding() } label: { BallotListElementView(ballot: ballot) } } } } This portion works in the editor. When the ballot is selected, the editor populates the selected candidate choices, and the editing works. However, when I attempt to insert BallotsView into a TabView, the NavigationLink stops working as expected. I didn't think NavigationLink was the proper way to do this, but it had been working. TabView { Tab("Ballots", systemImage: "menucard") { BallotsView(document: $document) } Tab { CandidateView() } label: { Text("Candidates") } .tabViewStyle(.sidebarAdaptable) } This is my third iteration. I have tried using a List with selection, but in that case, I am unable to pass the binding to the detail view. I just don't understand how this works, and I am preparing a version in Cocoa so that I don't have to deal with it anymore.
2
0
93
Jun ’25
Emulate AppKit NSPopUpButton in SwiftUI
How to make a control that looks and feels as close as possible to NSPopUpButton in SwiftUI, so a Mac user accepts the control as being native Mac UI? Items should have icon and text, I need separators between some items and certain items may be disabled at times, so they should not be selectable. Picker seems to lack some of those features (separators and disabled items), and Menu looks and behaves differently. Any guidance? For now I went with Menu, but find both the "chevron.down" icon at the trailing end as well as the positioning of the menu below the control weird.
Topic: UI Frameworks SubTopic: SwiftUI
2
0
97
Jun ’25
Where is preferredFilenameExtension getting its information?
If I use [UTType exportedTypeWithIdentifier:] to get one of the types in my app's Info.plist, and then ask for the preferredFilenameExtension of that UTType, I get the wrong extension, i.e., not the first file extension listed for that UTI in my Info.plist. Is this one of those situations where AppKit is looking in some database that can get out of sync with what's actually in the Info.plist?
Topic: UI Frameworks SubTopic: AppKit
2
0
113
Jul ’25
Custom, Markdown autocapitalizationType.
Hi, I've got an app that displays markdown in UITextView / NSTextView. I would like it to behave like Notes app does, that is if user types the line start modifier, e.g: "# " or "> " I would like the keyboard to show a capitalized letters. I've tried looking into overriding insertText - and it breaks the predictive text (can not insert white space). I've tried implementing UITextInputTokenizer but no luck either. Like I said, I see the Notes app does it perfectly, so maybe I'm missing something obvious or there is a way to do it without interrupting the auto-correction and predictive text. Ideally same thing can be applied to the NSTextView as the app support both platforms.
Topic: UI Frameworks SubTopic: UIKit Tags:
0
0
278
May ’25
iOS 26 Beta – Unexpected Shadow/Glow Around Fullscreen Video Player in SwiftUI
Hello everyone, I'm developing a SwiftUI app that includes a fullscreen video player (AVPlayerViewController or AVPlayerLayer). I'm currently testing the app on an iPhone 16 Pro running iOS 26 Beta, as well as on the corresponding simulator. With iOS 26, during video playback, an unexpected black or white glow/halo appears around the video, depending on the system appearance (dark/light mode). However, this issue does not occur when testing on iOS 18 — neither on device nor simulator. Has anyone encountered this issue? Is there any known workaround or solution to remove this visual effect on iOS 26? I've attached screenshot below to illustrate the problem. Thank you in advance for your help!
2
0
207
Jun ’25
The NSTextViewDelegate method textViewDidChangeSelection(:) will not fire, while all other text view delegate methods do.
I am trying to implement the NSTextViewDelegate function textViewDidChangeSelection(_ notification: Notification). My text view's delegate is the Coordinator of my NSViewRepresentable. I've found that this delegate function never fires, but any other delegate function that I implement, as long as it doesn't take a Notification as an argument, does fire (e.g., textView(:willChangeSelectionFromCharacterRange:toCharacterRange:), fires and is called on the delegate exactly when it should be). For context, I've verified all of the below: textView.isSelectable = true textView.isEditable = true textView.delegate === my coordinator I can call textViewDidChangeSelection(:) directly on the delegate without issue. I can select and edit text without issues. I.e., the selections are being set correctly. But the delegate method is never called when they are. I am able to add the intended delegate as an observer for the selector textViewDidChangeSelection via NotificationCenter. If I do this, the function executes when it should, but fires for every text view in my view hierarchy, which can number in the hundreds. I'm using an NSLayoutManager, so I figure this should only fire once. I've added a check within my code: func textViewDidChangeSelection(_ notification: Notification) { guard let textView = notification.object as? NSTextView, textView === layoutManager.firstTextView else { return } // Any code I want to execute... } But the above guard check lets through every notification, so, no matter what, my closure executes hundreds of times if I have hundreds of text views, all of them being sent by textView === layoutManager.firstTextView, but once for each and every text view managed by that layoutManager. Does anyone know why this method isn't ever called on the delegate, while seemingly all other delegate methods are? I could go the NotificationCenter route, but I'd love to know why this won't execute as a delegate method when documentation says that it should, and I don't want to have to implement a counter to make sure my code only executes once per selection update. And for more reasons than that, implementing via delegate method is preferable to using notifications for my use case. Thanks for any help!
3
0
271
May ’25
CarPlay and iOS 18.5, app crashes if the mobile one is not running
Hi, after upgrading to iOS 18.5 our app crashes in CarPlay. Only when the app is running on our mobile the carplay app works fine. If we run the same app in mobiles with iOS < 18.5 everything works. What has changed in iOS 18.5? Thanks
Replies
1
Boosts
0
Views
115
Activity
May ’25
sandbox causes the input method switch to fail to take effect
Dear Apple developers: Hello, recently I want to develop an application for macos that automatically switches input methods. The function is that when you switch applications, it can automatically switch to the input method you set, thus eliminating the trouble of manual switching. All the functions have been implemented, but only when the sandbox is closed. When I opened the sandbox, I found a very strange phenomenon. Suppose wechat was set to the Chinese input method. When I switched to wechat, wechat automatically got the focus of the input box. The input method icon in the upper right corner of the screen had actually switched successfully, but when I actually input, it was still the previous input method. If you switch to an application that does not have a built-in focus, the automatic switching of the input method will take effect when you click the input box with the mouse to regain the focus. This phenomenon is too difficult for my current technical level. I have tried many methods but none of them worked. I hope the respected experts can offer some ideas. Below is a snippet of the code switching I provided: DispatchQueue. Main. AsyncAfter (deadline: now () + 0.1) { let result = TISSelectInputSource(inputSource) if result == noErr { print(" Successfully switched to input method: \(targetInputMethod)") } else { print(" Input method switch failed. Error code: \(result)") } // Verify the switching result if let newInputSource = getCurrentInputSource() { print(" Switched input method: (newInputSource)") } } When the sandbox is opened, the synchronous switching does not take effect. The input method icon in the status bar will flash for a moment, unable to compete with system events. Even if it is set to DispatchQueue.main.async, it still does not work. It seems that there is a timing issue with the input method switching. Development environment macOS version: 15.4.1 Xcode version: 16.2
Replies
0
Boosts
0
Views
194
Activity
Jul ’25
Debug an issue with NSWindow becoming narrow
For months now we're trying to find an issue with one of our apps, were a window suddenly becomes narrow and can't be resized horizontally any more. It's a bug that only happens sporadically and we can't provide a "focused test project" to demonstrate the issue; thus we can't ask for code-level support at this moment. To debug this issue, we've overwritten a private method on NSWindow that gets the constrained window min and max sizes (valuable hint of Kristin from the AppKit team in a WWDC 2025 one-on-one session where I was able to show it to her in my debugger). When the bug hits, the maxSize's width (usually 10000) becomes smaller than the minSize's width. One way (but not the only one) to trigger this issue is to move the window from one display to another and back. Sometimes the bug triggers after a few back-and-forth movements, sometimes it takes minutes to trigger or I give up… but for other people the bug happens seemingly out of nowhere (of course there must be a trigger but we haven't noticed common patterns yet). It looks like an AutoLayout issue since a suspicious thing happens when the bug triggers: calling constraintsAffectingLayoutForOrientation:NSLayoutConstraintOrientationHorizontal on the NSThemeFrame usually returns just two constraints. But when the bug triggers, it returns a whole bunch of constraints, related to all kind of views of our app. Asking the NSThemeFrame for its direct constraints still shows the same two constraints are present and active (NSWindow-current-width and NSWindow-x-anchor). How to proceed in hunting down this issue when we're unable to produce a demo project? We can only reproduce the bug with our big product, and only sporadically: sometimes I can trigger it in a minute, sometimes it takes me 15 minutes or even more. Issue happens on macOS 15 (currently running 15.5).
Replies
1
Boosts
0
Views
168
Activity
Jul ’25
Glass effect on a stroke
I'm trying to apply a glass effect on a circle stroke but all it does is apply it to the circle itself and not the stroke: import SwiftUI let kCarouselCircleSize: CGFloat = 150 let kCarouselOpacity: Double = 0.3 let kCarouselStrokeWidth: CGFloat = 60 struct ContentView: View { @State var showing = false var body: some View { VStack(spacing: 60) { Text("ultraThinMaterial:") .font(.title) CarouseCircle(drawProgress: 0.7, isActive: false) Text("glassEffect()") .font(.title) CarouseCircle(useGlassEffect: true, drawProgress: 0.7, isActive: false) } .background(content: { Image(.background2) }) .padding() } } struct CarouseCircle: View { var size: CGFloat = kCarouselCircleSize var strokeWidth: CGFloat = kCarouselStrokeWidth var useGlassEffect: Bool = false var drawProgress: CGFloat var isActive: Bool var body: some View { if useGlassEffect { Circle() .trim(from: 0, to: drawProgress) .fill(.clear) .stroke(.blue, style: StrokeStyle(lineWidth: strokeWidth, lineCap: .round)) .frame(width: size, height: size) .glassEffect() .shadow(color: .black.opacity(kCarouselOpacity), radius: isActive ? 4 : 1, x: 0, y: 0) .rotationEffect(.degrees(-90)) // Start drawing at button 1's position } else { Circle() .trim(from: 0, to: drawProgress) .fill(.clear) .stroke(.ultraThinMaterial, style: StrokeStyle(lineWidth: strokeWidth, lineCap: .round)) .frame(width: size, height: size) .shadow(color: .black.opacity(kCarouselOpacity), radius: isActive ? 4 : 1, x: 0, y: 0) .rotationEffect(.degrees(-90)) // Start drawing at button 1's position } } } Here's the result: Is this supported, a bug or something I'm doing wrong?
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
0
Boosts
0
Views
186
Activity
Jul ’25
Crash due to likely infinitely recursive call in SwiftUI `Color.Resolved.init`
So I'm dealing with a really obtuse crash that appears to be a stack overflow in an internal SwiftUI code path creating a Color.Resolved. I haven't found anyone one else with this issue online, and I cannot get it to reproduce on my own device. Interestingly enough, it is only happening on 1 device in the field (according to XCode crash logs). Here are some lines from the crashed thread. You can see that my code is never called, and it appears to be starting in some Array equality check checking the equality of colors (which I can't think of anywhere in my app I am doing anyway). You can see from this trace here that it appears to be a recursive call through Color.Resolved and NSColor.withColorAppearance. I don't have any idea how to solve this, but it keeps happening with at least one in-the-field device across multiple app updates. So my whole app is open source on github at https://github.com/msdrigg/roam, but I don't even use NSColor explicitly anywhere except for here which doesn't match the stack trace. I also tried changing the accent color of the app with defaults write com.msdrigg.roam AppleAccentColor -integer 1 to see if that somehow caused the crash, but my app opened up totally fine (and respected the change). Besides this, the only places I think I could be using dynamic colors is I when define an AccentColor and a WidgetBackground color for my app using xcassets, and then I use these colors from SwiftUI. In most of my app I stick to the system colors (Color.gray and such). Thread 0 Crashed: 0 libsystem_pthread.dylib 0x000000018601213c ___chkstk_darwin + 60 1 CoreFoundation 0x0000000186108434 -[NSArray isEqualToArray:] + 52 (NSArray.m:454) 2 AppKit 0x000000018a21fcd4 -[NSCoreUICatalogColor resolvedCUINamedColorForAppearance:] + 164 (NSColor.m:5057) 3 AppKit 0x0000000189c32cd4 -[NSCoreUICatalogColor resolvedColor] + 48 (NSColor.m:5148) 4 AppKit 0x0000000189c31e74 -[NSDynamicNamedColor colorUsingColorSpace:] + 32 (NSColor.m:4410) 5 SwiftUICore 0x0000000221ca9fd8 CoreColorPlatformColorGetComponents + 116 (CoreColorFunctions.m:149) 6 SwiftUICore 0x0000000221faaf28 specialized Color.Resolved.init(platformColor:) + 92 (CoreColor.swift:14) 7 SwiftUICore 0x0000000221faa5b0 Color.Resolved.init(platformColor:) + 16 (<compiler-generated>:0) 8 SwiftUI 0x00000001b53b1dc4 closure #1 in NSColor.resolve(in:) + 20 (AppKitColorConversions.swift:156) 9 SwiftUI 0x00000001b53b222c partial apply for closure #1 in static NSColor.withColorAppearance(in:_:) + 32 (<compiler-generated>:0) 10 SwiftUI 0x00000001b46b1e54 closure #1 in SubmitTriggerSource.dispatchUpdate(_:) + 28 (PlatformViewCoordinator.swift:12) 11 SwiftUI 0x00000001b5484488 thunk for @escaping @callee_guaranteed () -> () + 28 (<compiler-generated>:0) 12 AppKit 0x0000000189c174a4 +[NSAppearance _performWithCurrentAppearance:usingBlock:] + 72 (NSAppearance.m:2408) 13 SwiftUI 0x00000001b53b2088 specialized static NSColor.withColorAppearance(in:_:) + 324 (AppKitColorConversions.swift:142) 14 SwiftUI 0x00000001b53b1e7c protocol witness for ColorProvider.resolve(in:) in conformance NSColor + 68 (<compiler-generated>:151) 15 SwiftUICore 0x0000000222436e6c ColorBox.resolve(in:) + 124 (Color.swift:288) 16 SwiftUICore 0x0000000222435e30 Color.resolve(in:) + 72 (Color.swift:87) 17 SwiftUI 0x00000001b53b1c88 closure #1 in NSColor.init(_:) + 196 (AppKitColorConversions.swift:124) 18 SwiftUI 0x00000001b4542714 thunk for @escaping @callee_guaranteed (@guaranteed NSAppearance) -> (@owned NSColor) + 56 (<compiler-generated>:0) 19 AppKit 0x0000000189c31e74 -[NSDynamicNamedColor colorUsingColorSpace:] + 32 (NSColor.m:4410) //// ... Repeating for 500 lines 500 SwiftUICore 0x0000000221ca9fd8 CoreColorPlatformColorGetComponents + 116 (CoreColorFunctions.m:149) 501 SwiftUICore 0x0000000221faaf28 specialized Color.Resolved.init(platformColor:) + 92 (CoreColor.swift:14) 502 SwiftUICore 0x0000000221faa5b0 Color.Resolved.init(platformColor:) + 16 (<compiler-generated>:0) 503 SwiftUI 0x00000001b53b1dc4 closure #1 in NSColor.resolve(in:) + 20 (AppKitColorConversions.swift:156) 504 SwiftUI 0x00000001b53b222c partial apply for closure #1 in static NSColor.withColorAppearance(in:_:) + 32 (<compiler-generated>:0) 505 SwiftUI 0x00000001b46b1e54 closure #1 in SubmitTriggerSource.dispatchUpdate(_:) + 28 (PlatformViewCoordinator.swift:12) 506 SwiftUI 0x00000001b5484488 thunk for @escaping @callee_guaranteed () -> () + 28 (<compiler-generated>:0) 507 AppKit 0x0000000189c174a4 +[NSAppearance _performWithCurrentAppearance:usingBlock:] + 72 (NSAppearance.m:2408) 508 SwiftUI 0x00000001b53b2088 specialized static NSColor.withColorAppearance(in:_:) + 324 (AppKitColorConversions.swift:142) 509 SwiftUI 0x00000001b53b1e7c protocol witness for ColorProvider.resolve(in:) in conformance NSColor + 68 (<compiler-generated>:151) 510 SwiftUICore 0x0000000222436e6c ColorBox.resolve(in:) + 124 (Color.swift:288) full-log.crash
Replies
0
Boosts
0
Views
146
Activity
May ’25
How to sync stroke between two PKCanvasViews with one in a UIScrollView with scale not 1
I got 3 PKCanvasView, 2 below the Major one. Users draw lines on the top one, then sync the last stroke to the one underneath. If the stroke crosses two PKCanvasView, we replace the stroke with a bezier curve. If a stroke doesn't cross regions, we sync the stroke to the one below it(B) as if it is drawn directly on B. The problem is if the B is inside a UIScrollview with a zoom scale not 1, the stroke from major to B will shrink or grow. Does anybody have a solution for this please? What I did Also put the major canvas into a uiScrollview, and make sure the zoomScale is the same as the B. for scale >=1, it works as expected, for scale < 1, sometimes it works, sometimes it doesn't. for example, 0.5, 0.6, 0.8, 0.5 doesn't work, 0.6, 0.8 works, I don't know why. What it costs It cost me 16*4 hours for these days. I didn't find a solution. Hopefully, some one can solve it.
Replies
0
Boosts
0
Views
252
Activity
Jul ’25
Mixing ReferenceFileDocument and @Observable
I have an app in which the data model is @Observable, and views see it through @Environment(dataModel.self) private var dataModel. Since there are a large number of views, only some of which may need to be redrawn at a given time, I believe that @Observable is more efficient at run time than @Published and @ObservedObject I’ve been trying to make the app document based. Although I started using SwiftData, it has trouble with Codable, and a long thread in the Developer forum suggests that SwiftData does not support the Undo manager - and in any event, simple JSON serialization is all that this app requires. Unfortunately, ReferenceFileDocument inherits from ObservableObject, which seems to not play nice with @Observable. I’d like to keep using @Observable, but haven’t been able to figure out how. When I deserialize a JSON ReferenceFileDocument, I can’t seem to connect it to an @Observable class instance and to let the various views and view models know where to find and update it. I’d appreciate advice on how to implement document persistence in this app. Also, the default behaviour of DoumentGroup provides a nice menu to, another things, rename a new file to something other than Untitled xx, but it doesn’t appear to work (there is an extensive thread on the Developer website discussing this issue). Is there a solution to this problem? Thanks for any help you can offer.
Replies
3
Boosts
0
Views
177
Activity
May ’25
Sections in LazyVStack jump/flicker on scroll
ScrollView(.vertical) { LazyVStack { ForEach(0..<700, id: \.self) { index in Section { Text("Content \(index)") .font(.headline) .padding() } header: { Text("Section \(index)") .font(.title) .padding() } } } } iOS: 18.5, iPhone 15 Pro Max, Xcode 16.4
Replies
0
Boosts
0
Views
223
Activity
Jul ’25
Resolving AppIntent in the app from a widget...
Is anyone familiar with AppIntents and their usage? I have an AppIntent defined in my widget extension. I have the same AppIntent defined in the app marked as ForegroundContinuableIntent. If I add the intent on a SwiftUI button and tap the Button it correctly resolves the app's version of the intent and performs that intent. However, what I really want to do is perform the AppIntent manually as the timeline updates but not more often than every hour (i.e. >= 1 hour). It's easy enough to handle the timing in the timeline. However, I do not know how to resolve the intent such that it calls the app's version of the intent (i.e. the same way that a Button does). If I just call perform it will run the version in the widget extension. The end goal is to minimally / periodically sync with the app. Thanks in advance for any help / advice on this.
Topic: UI Frameworks SubTopic: SwiftUI
Replies
3
Boosts
0
Views
151
Activity
Jun ’25
Window number too large
I'm trying to get information about my status items window. I get the window number using this call: statusItem.button?.window?.windowNumber With that number I try to determine if it visible or not. On macOS 15, this works fine, however on macOS Tahoe the window number is bigger than UInt32 or its type alias CGWindowID, causing a crash of my app (when converting from Int to UInt32). Somehow the window numbers were always in the 32-bit space. I can only guess about the reasons for increase of the window number beyond the UInt32 bounds. I don't know how the windows are numbered, but something may not be going as expected here. Anyone knows if this may be due to running in a virtual machine?
Topic: UI Frameworks SubTopic: General Tags:
Replies
1
Boosts
0
Views
107
Activity
Jun ’25
Liquid glass toolbar: showing wrong light/dark on load
I have a dark background and the initial look of the nav bar is showing like there is a light background. See picture. Has anyone experienced this or know of a solution? If I scroll the table up, it will fix itself and start behaving as I'd expect.
Topic: UI Frameworks SubTopic: UIKit Tags:
Replies
2
Boosts
0
Views
117
Activity
Jun ’25
SwiftUI: scrollEdgeEffectStyle(.hard, for: .all) bug with preferredColorScheme(.dark)
In the small example below, I have set .preferredColorScheme(.dark). I am pushing a view that has a List. I have a custom background color. When .scrollEdgeEffectStyle(.hard, for: .all) is used, the pushed view top and bottom safe areas flash black before being replaced by the blue background color. If I change this to .scrollEdgeEffectStyle(.soft, for: .all), the issue goes away. If I do not set preferredColorScheme(.dark), the issue also goes away. I filled FB18465023, but wonder if I am just doing something wrong? Video of sample running: https://www.youtube.com/shorts/87rWqHtdmKw. var body: some View { NavigationStack { VStack { Image(systemName: "globe") .imageScale(.large) .foregroundStyle(.tint) Text("Hello, world!") NavigationLink("Push New View") { PushedView() } .buttonStyle(.glass) .padding() } .frame(maxWidth: .infinity, maxHeight: .infinity) .ignoresSafeArea(.all) .background(.blue) } .preferredColorScheme(.dark) } } struct PushedView: View { @State private var searchText = "" var body: some View { List { ForEach(1...30, id: \.self) { index in Label("Label \(index)", systemImage: "number.circle") .listRowBackground(Color.blue) } } // This causes the top and bottom safe areas to start off black before // getting the blue background from below .scrollEdgeEffectStyle(.hard, for: .all) // This does not have the issue // .scrollEdgeEffectStyle(.hard, for: .all) .listStyle(.plain) .background(.blue) .searchable(text: $searchText, prompt: "Search labels...") .toolbar { ToolbarItem(placement: .topBarTrailing) { Button("Toolbar Button", systemImage: "questionmark") { print("touched") } } } } }
Topic: UI Frameworks SubTopic: SwiftUI
Replies
1
Boosts
0
Views
295
Activity
Jul ’25
The URL authorization read and write obtained by UIDocumentPickerViewController
The URL directory obtained by UIDocumentPickerVieweController can be read and written in the directory after calling startAccessingDecurityScopeResource. However, after restarting the app, if the URL saved in the package is called startAccessingDecurityScopeResource again and returns NO, UIDocumentPickerVieweController must be called again to retrieve the URL, and then startAccessingDecurityScopeResource must be called again before continuing the operation. This is too troublesome. Is there a way to continue reading and writing operations in the URL directory after restarting the app?
Replies
1
Boosts
0
Views
84
Activity
May ’25
Displaying an editing hierarchy in macOS
The SwiftUI Navigation structures work in ways that are not intuitive to me. For example, I am trying to display a set of data that represents rankings contained in a balloting system that I have created. The ballots all have candidates that are ranked from highest preference to lowest. Normally, I try to work backwards in SwiftUI, so I built the ballot editor to take a binding to the ballot itself: struct BallotEditor: View { @Binding var ballot: Election.Ballot var maxRank: Int var body: some View { VStack { ForEach($ballot.rankings) { $ranking in CandidateRankingPicker(maxRanking: maxRank, ranking: $ranking) } } } } This is embedded into a view with a list of ballots: struct BallotsView: View { @Binding var document: ElectionDocument var body: some View { List($document.ballots) { $ballot in NavigationLink { BallotEditor(ballot: $ballot, maxRank: document.election.candidates.count) .padding() } label: { BallotListElementView(ballot: ballot) } } } } This portion works in the editor. When the ballot is selected, the editor populates the selected candidate choices, and the editing works. However, when I attempt to insert BallotsView into a TabView, the NavigationLink stops working as expected. I didn't think NavigationLink was the proper way to do this, but it had been working. TabView { Tab("Ballots", systemImage: "menucard") { BallotsView(document: $document) } Tab { CandidateView() } label: { Text("Candidates") } .tabViewStyle(.sidebarAdaptable) } This is my third iteration. I have tried using a List with selection, but in that case, I am unable to pass the binding to the detail view. I just don't understand how this works, and I am preparing a version in Cocoa so that I don't have to deal with it anymore.
Replies
2
Boosts
0
Views
93
Activity
Jun ’25
Emulate AppKit NSPopUpButton in SwiftUI
How to make a control that looks and feels as close as possible to NSPopUpButton in SwiftUI, so a Mac user accepts the control as being native Mac UI? Items should have icon and text, I need separators between some items and certain items may be disabled at times, so they should not be selectable. Picker seems to lack some of those features (separators and disabled items), and Menu looks and behaves differently. Any guidance? For now I went with Menu, but find both the "chevron.down" icon at the trailing end as well as the positioning of the menu below the control weird.
Topic: UI Frameworks SubTopic: SwiftUI
Replies
2
Boosts
0
Views
97
Activity
Jun ’25
Where is preferredFilenameExtension getting its information?
If I use [UTType exportedTypeWithIdentifier:] to get one of the types in my app's Info.plist, and then ask for the preferredFilenameExtension of that UTType, I get the wrong extension, i.e., not the first file extension listed for that UTI in my Info.plist. Is this one of those situations where AppKit is looking in some database that can get out of sync with what's actually in the Info.plist?
Topic: UI Frameworks SubTopic: AppKit
Replies
2
Boosts
0
Views
113
Activity
Jul ’25
Custom, Markdown autocapitalizationType.
Hi, I've got an app that displays markdown in UITextView / NSTextView. I would like it to behave like Notes app does, that is if user types the line start modifier, e.g: "# " or "> " I would like the keyboard to show a capitalized letters. I've tried looking into overriding insertText - and it breaks the predictive text (can not insert white space). I've tried implementing UITextInputTokenizer but no luck either. Like I said, I see the Notes app does it perfectly, so maybe I'm missing something obvious or there is a way to do it without interrupting the auto-correction and predictive text. Ideally same thing can be applied to the NSTextView as the app support both platforms.
Topic: UI Frameworks SubTopic: UIKit Tags:
Replies
0
Boosts
0
Views
278
Activity
May ’25
iOS 26 Beta – Unexpected Shadow/Glow Around Fullscreen Video Player in SwiftUI
Hello everyone, I'm developing a SwiftUI app that includes a fullscreen video player (AVPlayerViewController or AVPlayerLayer). I'm currently testing the app on an iPhone 16 Pro running iOS 26 Beta, as well as on the corresponding simulator. With iOS 26, during video playback, an unexpected black or white glow/halo appears around the video, depending on the system appearance (dark/light mode). However, this issue does not occur when testing on iOS 18 — neither on device nor simulator. Has anyone encountered this issue? Is there any known workaround or solution to remove this visual effect on iOS 26? I've attached screenshot below to illustrate the problem. Thank you in advance for your help!
Replies
2
Boosts
0
Views
207
Activity
Jun ’25
The NSTextViewDelegate method textViewDidChangeSelection(:) will not fire, while all other text view delegate methods do.
I am trying to implement the NSTextViewDelegate function textViewDidChangeSelection(_ notification: Notification). My text view's delegate is the Coordinator of my NSViewRepresentable. I've found that this delegate function never fires, but any other delegate function that I implement, as long as it doesn't take a Notification as an argument, does fire (e.g., textView(:willChangeSelectionFromCharacterRange:toCharacterRange:), fires and is called on the delegate exactly when it should be). For context, I've verified all of the below: textView.isSelectable = true textView.isEditable = true textView.delegate === my coordinator I can call textViewDidChangeSelection(:) directly on the delegate without issue. I can select and edit text without issues. I.e., the selections are being set correctly. But the delegate method is never called when they are. I am able to add the intended delegate as an observer for the selector textViewDidChangeSelection via NotificationCenter. If I do this, the function executes when it should, but fires for every text view in my view hierarchy, which can number in the hundreds. I'm using an NSLayoutManager, so I figure this should only fire once. I've added a check within my code: func textViewDidChangeSelection(_ notification: Notification) { guard let textView = notification.object as? NSTextView, textView === layoutManager.firstTextView else { return } // Any code I want to execute... } But the above guard check lets through every notification, so, no matter what, my closure executes hundreds of times if I have hundreds of text views, all of them being sent by textView === layoutManager.firstTextView, but once for each and every text view managed by that layoutManager. Does anyone know why this method isn't ever called on the delegate, while seemingly all other delegate methods are? I could go the NotificationCenter route, but I'd love to know why this won't execute as a delegate method when documentation says that it should, and I don't want to have to implement a counter to make sure my code only executes once per selection update. And for more reasons than that, implementing via delegate method is preferable to using notifications for my use case. Thanks for any help!
Replies
3
Boosts
0
Views
271
Activity
May ’25
cornerConfiguration API not available for UIVisualEffectView()
Hi, There is new cornerConfiguration API introduced for UIVisualEffectView mentioned in tutorial below. https://developer.apple.com/videos/play/wwdc2025/284/ But it is not available to use as of now. Using Xcode 26 Beta 2. Please get it fixed.
Topic: UI Frameworks SubTopic: UIKit Tags:
Replies
2
Boosts
0
Views
187
Activity
Jul ’25