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

Summary of iOS/iPadOS 26 UIKit bugs related to UISearchController & UISearchBar using scope buttons
All of these issues appear when the search controller is set on the view controller's navigationItem and the search controller's searchBar has its scopeButtonTitles set. So far the following issues are affecting my app on iOS/iPadOS 26 as of beta 7: When the scopeBarActivation of UISearchController is set to .onSearchActivation, the preferredSearchBarPlacement of the navigationItem is set to .integratedButton, and the searchBarPlacementAllowsToolbarIntegration is set to false (forcing the search icon to appear in the nav bar), on both iPhones and iPads, the scope buttons never appear. They don't appear when the search is activated. They don't appear when any text is entered into the search bar. FB19771313 I attempted to work around that issue by setting the scopeBarActivation to .manual. I then show the scope bar in the didPresentSearchController delegate method and hide the scope bar in the willDismissSearchController. On an iPhone this works though the display is a bit clunky. On an iPad, the scope bar does appear via the code in didPresentSearchController, but when any scope bar button is tapped, the search controller is dismissed. This happens when the app is horizontally regular. When the app on the iPad is horizontally compact, the buttons work but the search bar's text is not correctly aligned within the search bar. Quite the mess really. I still need to post a bug report for this issue. But if issue 1 above is fixed then I don't need this workaround. When the scopeBarActivation of UISearchController is set to .onSearchActivation, the preferredSearchBarPlacement of the navigationItem is set to .stacked, and the hidesSearchBarWhenScrolling property of the navigationItem is set to false (always show the search bar), and this is all used in a UITableViewController, then upon initial display of the view controller on an iPhone or iPad, you are unable to tap on the first row of the table view except on the very bottom of the row. The currently hidden scope bar is stealing the touches. If you activate and then cancel the search (making the scope bar appear and then disappear) then you are able to tap on the first row as expected. The initially hidden scope bar also bleeds through the first row of the table. It's faint but you can tell it's not quite right. Again, this is resolved by activating and then canceling the search once. FB17888632 When the scopeBarActivation of UISearchController is set to .onSearchActivation, the preferredSearchBarPlacement of the navigationItem is set to integrated or .integratedButton, and the toolbar is shown, then on iPhones (where the search bar/icon appears in the toolbar) the scope buttons appear (at the top of the screen) the first time the search is activated. But if you cancel the search and then activate it again, the search bar never appears a second (or later) time. On an iPad the search bar/icon appears in the nav bar and you end up with the same issue as #1 above. FB17890125 Issues 3 and 4 were reported against beta 1 and still haven't been fixed. But if issue 1 is resolved on iPhone, iPad, and Mac (via Mac Catalyst), then I personally won't be affected by issues 2, 3, or 4 any more (but of course all 4 issues need to be fixed). And by resolved, I mean that the scope bar appears and disappears when it is supposed to each and every time the search is activated and cancelled (not just the first time). The scope bar doesn't interfere with touch events upon initial display of the view controller. And there are no visual glitches no matter what the horizontal size class is on an iPad. I really hope the UIKit team can get these resolved before iOS/iPadOS 26 GM.
11
6
1.7k
2w
UIView wrapper around a View
I couldn't decide whether to post this question here or in SwiftUI Q&A as there's a lot of overlaps. We're trying to create something similar to UIViewRepresentable for UIKit. This might not work for complicated cases where the View has many pieces but as long as it works for simple cases, we're happy. The only problem right now is figuring out the correct height. Currently, the height anchor is assigned to CGFloat.greatestFiniteMagnitude, which works but when inspecting the layout in View Hierarchy, it appears the wrapped view is getting stretched all the way down. Also, sometimes View Hierarchy isn't able to draw the wrapped View and I'm unsure if it's a problem of View Hierarchy or our implementation. final public class SwiftUIConfigurationContainerView<T: View>: UIView { private var contentView: UIView? public override var intrinsicContentSize: CGSize { contentView?.intrinsicContentSize ?? super.intrinsicContentSize } private var preferredContentSize: CGSize? public init(@ViewBuilder _ content: @escaping () -> T) { super.init(frame: .zero) setUpContentView(content) } @available(*, unavailable) required init?(coder: NSCoder) { return nil } private func setUpContentView(_ content: @escaping () -> T) { let contentView = UIHostingConfiguration { [weak self] in VStack(spacing: .zero) { content() .onGeometryChange(for: CGSize.self, of: \.size) { size in self?.preferredContentSize = size self?.invalidateIntrinsicContentSize() } .frame(maxWidth: .infinity, alignment: .center) Spacer(minLength: .zero) } } .minSize(width: .zero, height: .zero) .margins(.all, .zero) .makeContentView() self.contentView = contentView addSubview(contentView) contentView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ contentView.leadingAnchor.constraint(equalTo: leadingAnchor), contentView.trailingAnchor.constraint(equalTo: trailingAnchor), contentView.topAnchor.constraint(equalTo: topAnchor), contentView.heightAnchor.constraint(equalToConstant: CGFloat.greatestFiniteMagnitude), ]) } }
0
0
164
2w
SwiftUI ​Charts: In iOS 27, annotation overlays exceed the bounds of an annotation
I'm seeing a regression in SwiftUI Charts on iOS 27 beta 1. Any view placed inside a BarMark's overlay annotation no longer receives the size of the parent BarMark. It collapses to zero, so any content sized from geo.size (e.g. a Rectangle meant to fill the bar) renders empty or incorrectly. Expected: The GeometryReader reports the BarMark's rendered width/height, and the Rectangle fills the BarMark (this is the behavior in iOS 26 and earlier). Actual: On iOS 27 beta 1, geo.size is effectively zero, so the overlay content has an extremely small size. I suspect this could be a small bug with the new ContentBuilder / ViewBuilder changes but that's just a hunch. Here's a code sample which reproduces the issue. // MARK: - Mock Data Models struct ScheduleSeries: Identifiable { let id = UUID() let data: [ScheduleItem] } struct ScheduleItem: Identifiable { let id = UUID() let startDate: Date let startHour: Double let endHour: Double let secondaryText: String? } // MARK: - Minimal Reproducible Example struct ContentView: View { // Generate two consecutive days for the mock data let mockSchedule: [ScheduleSeries] = [ ScheduleSeries(data: [ ScheduleItem( startDate: Date(), startHour: 9.0, endHour: 11.5, secondaryText: "Morning Event" ), ScheduleItem( startDate: Calendar.current.date(byAdding: .day, value: 1, to: Date())!, startHour: 13.0, endHour: 16.0, secondaryText: "Afternoon Event" ) ]) ] var body: some View { VStack(alignment: .leading) { Text("FB: Annotation Sizing Bug") .font(.headline) .padding(.bottom, 8) Text("Expected: The gray Rectangle should stretch to fill the BarMark.\nActual: GeometryReader/Annotation fails to size to the parent BarMark.") .font(.caption) .foregroundColor(.secondary) .padding(.bottom) Chart(mockSchedule) { series in ForEach(series.data, id: \.startDate) { element in BarMark( x: .value("Day", element.startDate, unit: .day, calendar: .current), yStart: .value("Start", element.startHour), yEnd: .value("End", element.endHour), width: .ratio(0.99) ) .annotation(position: .overlay, alignment: .topLeading) { item in ZStack { VStack(alignment: .leading, spacing: 0) { // BUG DEMONSTRATION: // This GeometryReader and Rectangle previously filled the BarMark, but in Xcode 27 it does not GeometryReader { geo in Rectangle() .fill(Color.black.opacity(0.15)) .frame(width: geo.size.width, height: geo.size.height) } } .foregroundColor(.white) .font(.caption2) } } } } .chartYScale(domain: 0...24) // Lock the Y-axis to a 24-hour scale } .padding() } } Environment: Xcode 27 beta 1 / iOS 27 beta 1 Reproduces on device and Simulator Worked as expected on iOS 26 and earlier Here's what the issue looks like in our app with zero code changes: iOS 26 iOS 27 I've filed a feedback report (FB23016343) with a sample project attached. Has anyone else hit this, or found a workaround for sizing overlay annotation content to a BarMark in iOS 27? Thanks!
0
0
93
2w
How to detect backspace in SwiftUI TextField without falling back to UIViewRepresentable?
I'm building a multi-box PIN/OTP input in SwiftUI. In UIKit, I used UITextFieldDelegate to detect backspace presses on an empty field to move focus backward. SwiftUI’s .onChange(of: text) only triggers when text is actually deleted, completely missing backspaces on an already empty field. Is there a pure SwiftUI way to handle this now, or are we still forced to wrap UITextField via UIViewRepresentable?
1
0
103
2w
Source view disappearing when interrupting a zoom navigation transition
When I use the .zoom transition in a navigation stack, I get a glitch when interrupting the animation by swiping back before it completes. When doing this, the source view disappears. I can still tap it to trigger the navigation again, but its not visible on screen. This seems to be a regression in iOS 26, as it works as expected when testing on iOS 18. Has someone else seen this issue and found a workaround? Is it possible to disable interrupting the transition? Filed a feedback on the issue FB19601591 Screen recording: https://share.icloud.com/photos/04cio3fEcbR6u64PAgxuS2CLQ Example code @State var showDetail = false @Namespace var namespace var body: some View { NavigationStack { ScrollView { showDetailButton } .navigationTitle("Title") .navigationBarTitleDisplayMode(.inline) .navigationDestination(isPresented: $showDetail) { Text("Detail") .navigationTransition(.zoom(sourceID: "zoom", in: namespace)) } } } var showDetailButton: some View { Button { showDetail = true } label: { Text("Show detail") .padding() .background(.green) .matchedTransitionSource(id: "zoom", in: namespace) } } }
Topic: UI Frameworks SubTopic: SwiftUI
20
25
2.4k
2w
Programatic scroll edge effect for NSScrollView
Just like NSScrollView lets us programmatically set the contentInset in parallel to automaticallyAdjustsContentInsets, I think there should be similar functionality for blurring effect caused by scroll edge effect. I should be able programmatically set it. If the user is manually setting the contentInset then they can simply set a boolean, which when enabled will show edge effect when the scroll document goes outside the area of inset. Eg: scrollView.contentInsets = NSEdgeInsets(top: 100, left: 0, bottom: 0, right: 0) For contentInset like above set by user, they could set edge effect in two ways Automatically: scrollView.enableEdgeEffectOutsideInsets = true // This will apply edge effect based on frame size of contentInsets Programmatically: scrollView.edgeInsetEffectFrame = NSRect...
Topic: UI Frameworks SubTopic: AppKit
5
1
227
2w
Is there a better way to hide a view in a custom Layout other than placing it off-screen?
I have a custom Layout that places a number of labels for a cell footer in a certain way based on the available width that needs to conditionally hide those views that do not entirely fit anymore (based on some priorities I specify). Currently I simply move the subviews that do not fit anymore off-screen and use clipping to hide them outside the layout, as I did not find an "official" way to hide / exclude a subview from a Layout. Does anyone know a better / nicer way to do this in SwiftUI?
Topic: UI Frameworks SubTopic: SwiftUI
0
0
43
2w
Pass data to an @Observable model
Overview I have a navigation split view. The detail view contains a model now this model depends on id from the parent view. Questions How can I pass data from the parent view and yet create the view in the detail view? Or should I be pass the model from the parent view, but the problem is the parent view needs to persist model. Or is there a better approach?
0
0
52
2w
AsyncRenderer stack limit
We've been getting stack overflows in code we don't control, in the background AsyncRenderer thread in a chain of calls to updateInheritedViewAsync. But the stack is less than 200 calls deep, presumably because it's a background thread with a smaller stack limit. Is it possible to adjust AsyncRenderer's stack limit? Or otherwise, what limits should we be aware of to prevent running into this issue? com.apple.SwiftUI.AsyncRenderer: EXC_BAD_ACCESS (code=2, address=0x16f5ebe30) #0 0x000000019c6b4460 in function signature specialization <Arg[3] = Dead> of static SwiftUI.DisplayList.ViewUpdater.Model.merge(item: inout SwiftUI.DisplayList.Item, index: SwiftUI.DisplayList.Index, into: inout SwiftUI.DisplayList.ViewUpdater.Model.State) -> SwiftUI.DisplayList.ViewUpdater.Model.MergedViewRequirements () #1 0x000000019c7c2850 in SwiftUI.DisplayList.ViewUpdater.updateInheritedViewAsync(platform: SwiftUI.DisplayList.ViewUpdater.Platform, oldItem: SwiftUI.DisplayList.Item, oldParentState: Swift.UnsafePointer<SwiftUI.DisplayList.ViewUpdater.Model.State>, newItem: SwiftUI.DisplayList.Item, newParentState: Swift.UnsafePointer<SwiftUI.DisplayList.ViewUpdater.Model.State>) -> Swift.Optional<SwiftUI.Time> () #2 0x000000019c7c3ef0 in SwiftUI.DisplayList.ViewUpdater.updateInheritedViewAsync(platform: SwiftUI.DisplayList.ViewUpdater.Platform, oldItem: SwiftUI.DisplayList.Item, oldParentState: Swift.UnsafePointer<SwiftUI.DisplayList.ViewUpdater.Model.State>, newItem: SwiftUI.DisplayList.Item, newParentState: Swift.UnsafePointer<SwiftUI.DisplayList.ViewUpdater.Model.State>) -> Swift.Optional<SwiftUI.Time> () #3 0x000000019c7c3ef0 in SwiftUI.DisplayList.ViewUpdater.updateInheritedViewAsync(platform: SwiftUI.DisplayList.ViewUpdater.Platform, oldItem: SwiftUI.DisplayList.Item, oldParentState: Swift.UnsafePointer<SwiftUI.DisplayList.ViewUpdater.Model.State>, newItem: SwiftUI.DisplayList.Item, newParentState: Swift.UnsafePointer<SwiftUI.DisplayList.ViewUpdater.Model.State>) -> Swift.Optional<SwiftUI.Time> () #4 0x000000019c7c3ef0 in SwiftUI.DisplayList.ViewUpdater.updateInheritedViewAsync(platform: SwiftUI.DisplayList.ViewUpdater.Platform, oldItem: SwiftUI.DisplayList.Item, oldParentState: Swift.UnsafePointer<SwiftUI.DisplayList.ViewUpdater.Model.State>, newItem: SwiftUI.DisplayList.Item, newParentState: Swift.UnsafePointer<SwiftUI.DisplayList.ViewUpdater.Model.State>) -> Swift.Optional<SwiftUI.Time> () ... #147 0x000000019c7c364c in SwiftUI.DisplayList.ViewUpdater.updateInheritedViewAsync(platform: SwiftUI.DisplayList.ViewUpdater.Platform, oldItem: SwiftUI.DisplayList.Item, oldParentState: Swift.UnsafePointer<SwiftUI.DisplayList.ViewUpdater.Model.State>, newItem: SwiftUI.DisplayList.Item, newParentState: Swift.UnsafePointer<SwiftUI.DisplayList.ViewUpdater.Model.State>) -> Swift.Optional<SwiftUI.Time> () #148 0x000000019c7c2074 in SwiftUI.DisplayList.ViewUpdater.updateAsync(platform: SwiftUI.DisplayList.ViewUpdater.Platform, oldList: SwiftUI.DisplayList, oldParentState: Swift.UnsafePointer<SwiftUI.DisplayList.ViewUpdater.Model.State>, newList: SwiftUI.DisplayList, newParentState: Swift.UnsafePointer<SwiftUI.DisplayList.ViewUpdater.Model.State>) -> Swift.Optional<SwiftUI.Time> () #149 0x000000019c7c1a78 in renderAsync () #150 0x000000019c60fc68 in renderDisplayList () #151 0x000000019c612094 in protocol witness for SwiftUI.ViewGraphRenderHost.renderDisplayList(_: SwiftUI.DisplayList, asynchronously: Swift.Bool, time: SwiftUI.Time, nextTime: SwiftUI.Time, targetTimestamp: Swift.Optional<SwiftUI.Time>, version: SwiftUI.DisplayList.Version, maxVersion: SwiftUI.DisplayList.Version) -> SwiftUI.Time in conformance SwiftUI.ViewGraph : SwiftUI.ViewGraphRenderHost in SwiftUI () #152 0x000000019c7c0dd0 in renderAsync () #153 0x000000019c7be6c8 in SwiftUI.ViewGraphHost.displayLinkTimer(timestamp: SwiftUI.Time, targetTimestamp: SwiftUI.Time, isAsyncThread: Swift.Bool) -> () () #154 0x000000019c7beab8 in SwiftUI.ViewGraphDisplayLink.displayLinkTimer(__C.CADisplayLink) -> () () #155 0x000000019c7be5a8 in @objc SwiftUI.ViewGraphDisplayLink.displayLinkTimer(__C.CADisplayLink) -> () () #156 0x0000000192fdbb24 in CA::Display::DisplayLinkItem::dispatch_ () #157 0x0000000192fb9164 in CA::Display::DisplayLink::dispatch_items () #158 0x0000000192f91870 in display_timer_callback () #159 0x000000019256d4cc in __CFMachPortPerform () #160 0x000000019259d0b0 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ () #161 0x000000019259cfd8 in __CFRunLoopDoSource1 () #162 0x0000000192574c1c in __CFRunLoopRun () #163 0x0000000192573a6c in _CFRunLoopRunSpecificWithOptions () #164 0x0000000190533f54 in -[NSRunLoop(NSRunLoop) runMode:beforeDate:] () #165 0x000000018fb9a51c in -[NSRunLoop(NSRunLoop) run] () #166 0x000000019c7cd5b0 in function signature specialization <Arg[1] = Dead> of static SwiftUI.ViewGraphDisplayLink.asyncThread(arg: Swift.Optional<Any>) -> () () #167 0x000000019c7cd288 in @objc static SwiftUI.ViewGraphDisplayLink.asyncThread(arg: Swift.Optional<Any>) -> () () #168 0x000000018fbf321c in __NSThread__start__ () #169 0x00000001ef0d044c in _pthread_start ()
Topic: UI Frameworks SubTopic: SwiftUI
2
1
140
2w
How to obtain an app icon regardless of current icon style?
Hey Team, Using NSWorkspace.icon(forFile:) and pointing to an app bundle, the system returns an NSImage with the icon of the app, but in the current style. For example, if the user selected tinted icons in Appearance in System Settings, then any icon I receive back from the API will be tinted using the current accent color. Is there a way to override this and get the original icon? Thanks, Ari
Topic: UI Frameworks SubTopic: AppKit
3
1
148
2w
Making View's init nonisolated with environment variables
Views with custom nonisolated init fail to compile when using @MainActor-isolated @Environment properties (e.g., \.openURL, \.dismiss). From the Swift 6 migration documentation, it seems encouraged to define inits nonisolated, and it seems base SwiftUI components also have their inits defined as nonisolated (e.g. TimelineView, LazyHStack, etc), which makes sense. How do you achieve marking a SwiftUI View's init as nonisolated when it uses environment variables, without producing the following build error "Main actor-isolated default value of 'self.openURL' cannot be used in a nonisolated initalizer" ? It seems @State variable defined in a view has the ability to be set in a nonisolated init but not @Environment. What mechanism prevents this under the hood ?
Topic: UI Frameworks SubTopic: SwiftUI
7
0
148
2w
How to get the glassy picker showed at WWD27
In the session "What’s new in SwiftUI", at 02:38 Steven shows various Liquid Glass components, among them, a very pretty interactive glassy Picker. At first I thought this was built into the system and tried everything possible, until to rewatch the presentation and notice this: "On macOS, like on iOS, you can mark Liquid Glass custom elements as "interactive" so they respond more fluidly to user's clicks. And this is optimized to work great with the mouse pointer, so it feels right at home on the Mac." Does anyone have pointers to where one can find a Picker that implements all these system behaviors that folks have come to expect? I have my own version, which is deeply lacking, and so is every other implementation out there that I saw, and I thought sprinkling some "interactive" as instructed would help, but it barely made a dent.
Topic: UI Frameworks SubTopic: SwiftUI
2
0
180
2w
Best practice for activating a menubar app
Hey Team, I'm developing an app that normally resides in the menu bar and has no Dock icon (activation policy set to accessory. When the user clicks the status icon, and selects 'Settings' in the menu, I change the activation policy to regular, show the window, and activate the app. Since cooperative activation was introduced, the option to ignore all apps when activating was deprecated, so I activate the app without the option. The result is that in 20% of the times, the window doesn't come to the front, or the app is not activated. The user obviously wants this behavior, so what is the proper way to achieve it? Thanks, Ari
Topic: UI Frameworks SubTopic: AppKit
4
3
152
2w
Dynamic layouts with multi-line Text views
For a dynamic layout reacting to width changes using ViewThatFits, I need a 2-line Text view where content gets wrapped exactly once, but doesn't get abbreviated. If the text is too long to fit in two lines, ViewThatFits should choose the next layout. I tried to use .lineLimit(2, reservesSpace: true), but then ViewThatFits always takes this layout even when the text content gets too long to fit, so it gets abbreviated with "...", instead of choosing the next layout. How else can I build a layout with a two-line Text, which does signal to ViewThatFits if the space doesn't fit the entire text so it can choose the next layout?
Topic: UI Frameworks SubTopic: SwiftUI
2
0
112
2w
How to avoid trailing toolbar item re-rendering on child navigation
I have a NavigationStack where every child view except the root has a trailing close button. On each child view transition, the button re-renders itself. Is there a way to fix the button? I saw in the Apple Developer app the behavior I want when registering a lab and the confirmation screen, but I think the implementation is just changing the center content of the view and it isn't pushing a new view to the stack path that has different toolbar items. Root: VStack { Content Next button --> Page 2 } Cancel button leading edge Page 2: VStack { Copy Next button --> page 3 } built in back button leading edge cancel button trailing edge Page 3: VStack { Copy Finish button --> dismisses whole workflow } built in back button leading edge cancel button trailing edge So on page 3, the cancel button is new. I can't figure out how to not have the glass effect animate it in new. I want the 'same' cancel button to be there. This is an oversimplification of a resumable form where the user can cancel (save and resume) at any time. Is there a built in way to have the trailing edge button be fixed? Would moving where the button is defined make a different and expose a way for each child view to propagate upwards if the cancel button should be shown or not? Updated with sample, assumes iOS 18 + 26 code so using .topTrailing not new 'action' placement: import SwiftUI struct Demo: View { @State private var path: [String] = [] var body: some View { NavigationStack(path: $path) { Button("Go") { path.append("Second") } .navigationDestination(for: String.self) { destination in switch destination { case "Second": VStack { Text("Second") Button("Next") { path.append("Third") } } .toolbar { ToolbarItem(placement: .topBarTrailing) { Button("Close", role: .cancel) { path = [] } } } case "Third": VStack { Text("Third") Button("Finish") { path = [] } } .toolbar { ToolbarItem(placement: .topBarTrailing) { Button("Close", role: .cancel) { path = [] } } } default: Text("Undefined") } } } } }
Topic: UI Frameworks SubTopic: SwiftUI
2
0
96
2w
Correct UIScene Configuration for UISceneAccessory
What is the correct configuration of the Info.plist to get a UISceneAccessory to display on an external monitor? I'm currently getting: Info.plist contained no UIScene configuration dictionary (looking for configuration named "scene-accessory") My Info.plist looks as follows: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>UIApplicationSceneManifest</key> <dict> <key>UIApplicationSupportsMultipleScenes</key> <true/> <key>UISceneConfigurations</key> <dict> <key>UIWindowSceneSessionRoleExternalDisplayNonInteractive</key> <array> <dict> <key>UISceneDelegateClassName</key> <string>$(PRODUCT_MODULE_NAME).AccessorySceneDelegate</string> <key>UISceneConfigurationName</key> <string>scene-accessory</string> </dict> </array> <key>UIWindowSceneSessionRoleApplication</key> <array> <dict> <key>UISceneConfigurationName</key> <string>Default Configuration</string> <key>UISceneDelegateClassName</key> <string>$(PRODUCT_MODULE_NAME).SceneDelegate</string> </dict> </array> </dict> </dict> </dict> </plist> And the view controller scene registration code: class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() let sceneConfiguration = UISceneConfiguration(name: "scene-accessory") let accessory = UISceneAccessory.externalNonInteractive(sceneConfiguration: sceneConfiguration) let registration = registerSceneAccessory(accessory) registration.isEnabled = true } } Thanks!
Topic: UI Frameworks SubTopic: UIKit
1
0
162
2w
Dynamic Property inplace of onChange, task.
In the recent SwiftUI Group Lab, they mentioned using Dynamic Property instead of onChange, How to do it? Could it used as an actual property type instead of just using in combination with @propertyWrapper
Replies
0
Boosts
1
Views
109
Activity
2w
Summary of iOS/iPadOS 26 UIKit bugs related to UISearchController & UISearchBar using scope buttons
All of these issues appear when the search controller is set on the view controller's navigationItem and the search controller's searchBar has its scopeButtonTitles set. So far the following issues are affecting my app on iOS/iPadOS 26 as of beta 7: When the scopeBarActivation of UISearchController is set to .onSearchActivation, the preferredSearchBarPlacement of the navigationItem is set to .integratedButton, and the searchBarPlacementAllowsToolbarIntegration is set to false (forcing the search icon to appear in the nav bar), on both iPhones and iPads, the scope buttons never appear. They don't appear when the search is activated. They don't appear when any text is entered into the search bar. FB19771313 I attempted to work around that issue by setting the scopeBarActivation to .manual. I then show the scope bar in the didPresentSearchController delegate method and hide the scope bar in the willDismissSearchController. On an iPhone this works though the display is a bit clunky. On an iPad, the scope bar does appear via the code in didPresentSearchController, but when any scope bar button is tapped, the search controller is dismissed. This happens when the app is horizontally regular. When the app on the iPad is horizontally compact, the buttons work but the search bar's text is not correctly aligned within the search bar. Quite the mess really. I still need to post a bug report for this issue. But if issue 1 above is fixed then I don't need this workaround. When the scopeBarActivation of UISearchController is set to .onSearchActivation, the preferredSearchBarPlacement of the navigationItem is set to .stacked, and the hidesSearchBarWhenScrolling property of the navigationItem is set to false (always show the search bar), and this is all used in a UITableViewController, then upon initial display of the view controller on an iPhone or iPad, you are unable to tap on the first row of the table view except on the very bottom of the row. The currently hidden scope bar is stealing the touches. If you activate and then cancel the search (making the scope bar appear and then disappear) then you are able to tap on the first row as expected. The initially hidden scope bar also bleeds through the first row of the table. It's faint but you can tell it's not quite right. Again, this is resolved by activating and then canceling the search once. FB17888632 When the scopeBarActivation of UISearchController is set to .onSearchActivation, the preferredSearchBarPlacement of the navigationItem is set to integrated or .integratedButton, and the toolbar is shown, then on iPhones (where the search bar/icon appears in the toolbar) the scope buttons appear (at the top of the screen) the first time the search is activated. But if you cancel the search and then activate it again, the search bar never appears a second (or later) time. On an iPad the search bar/icon appears in the nav bar and you end up with the same issue as #1 above. FB17890125 Issues 3 and 4 were reported against beta 1 and still haven't been fixed. But if issue 1 is resolved on iPhone, iPad, and Mac (via Mac Catalyst), then I personally won't be affected by issues 2, 3, or 4 any more (but of course all 4 issues need to be fixed). And by resolved, I mean that the scope bar appears and disappears when it is supposed to each and every time the search is activated and cancelled (not just the first time). The scope bar doesn't interfere with touch events upon initial display of the view controller. And there are no visual glitches no matter what the horizontal size class is on an iPad. I really hope the UIKit team can get these resolved before iOS/iPadOS 26 GM.
Replies
11
Boosts
6
Views
1.7k
Activity
2w
UIView wrapper around a View
I couldn't decide whether to post this question here or in SwiftUI Q&A as there's a lot of overlaps. We're trying to create something similar to UIViewRepresentable for UIKit. This might not work for complicated cases where the View has many pieces but as long as it works for simple cases, we're happy. The only problem right now is figuring out the correct height. Currently, the height anchor is assigned to CGFloat.greatestFiniteMagnitude, which works but when inspecting the layout in View Hierarchy, it appears the wrapped view is getting stretched all the way down. Also, sometimes View Hierarchy isn't able to draw the wrapped View and I'm unsure if it's a problem of View Hierarchy or our implementation. final public class SwiftUIConfigurationContainerView<T: View>: UIView { private var contentView: UIView? public override var intrinsicContentSize: CGSize { contentView?.intrinsicContentSize ?? super.intrinsicContentSize } private var preferredContentSize: CGSize? public init(@ViewBuilder _ content: @escaping () -> T) { super.init(frame: .zero) setUpContentView(content) } @available(*, unavailable) required init?(coder: NSCoder) { return nil } private func setUpContentView(_ content: @escaping () -> T) { let contentView = UIHostingConfiguration { [weak self] in VStack(spacing: .zero) { content() .onGeometryChange(for: CGSize.self, of: \.size) { size in self?.preferredContentSize = size self?.invalidateIntrinsicContentSize() } .frame(maxWidth: .infinity, alignment: .center) Spacer(minLength: .zero) } } .minSize(width: .zero, height: .zero) .margins(.all, .zero) .makeContentView() self.contentView = contentView addSubview(contentView) contentView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ contentView.leadingAnchor.constraint(equalTo: leadingAnchor), contentView.trailingAnchor.constraint(equalTo: trailingAnchor), contentView.topAnchor.constraint(equalTo: topAnchor), contentView.heightAnchor.constraint(equalToConstant: CGFloat.greatestFiniteMagnitude), ]) } }
Replies
0
Boosts
0
Views
164
Activity
2w
SwiftUI ​Charts: In iOS 27, annotation overlays exceed the bounds of an annotation
I'm seeing a regression in SwiftUI Charts on iOS 27 beta 1. Any view placed inside a BarMark's overlay annotation no longer receives the size of the parent BarMark. It collapses to zero, so any content sized from geo.size (e.g. a Rectangle meant to fill the bar) renders empty or incorrectly. Expected: The GeometryReader reports the BarMark's rendered width/height, and the Rectangle fills the BarMark (this is the behavior in iOS 26 and earlier). Actual: On iOS 27 beta 1, geo.size is effectively zero, so the overlay content has an extremely small size. I suspect this could be a small bug with the new ContentBuilder / ViewBuilder changes but that's just a hunch. Here's a code sample which reproduces the issue. // MARK: - Mock Data Models struct ScheduleSeries: Identifiable { let id = UUID() let data: [ScheduleItem] } struct ScheduleItem: Identifiable { let id = UUID() let startDate: Date let startHour: Double let endHour: Double let secondaryText: String? } // MARK: - Minimal Reproducible Example struct ContentView: View { // Generate two consecutive days for the mock data let mockSchedule: [ScheduleSeries] = [ ScheduleSeries(data: [ ScheduleItem( startDate: Date(), startHour: 9.0, endHour: 11.5, secondaryText: "Morning Event" ), ScheduleItem( startDate: Calendar.current.date(byAdding: .day, value: 1, to: Date())!, startHour: 13.0, endHour: 16.0, secondaryText: "Afternoon Event" ) ]) ] var body: some View { VStack(alignment: .leading) { Text("FB: Annotation Sizing Bug") .font(.headline) .padding(.bottom, 8) Text("Expected: The gray Rectangle should stretch to fill the BarMark.\nActual: GeometryReader/Annotation fails to size to the parent BarMark.") .font(.caption) .foregroundColor(.secondary) .padding(.bottom) Chart(mockSchedule) { series in ForEach(series.data, id: \.startDate) { element in BarMark( x: .value("Day", element.startDate, unit: .day, calendar: .current), yStart: .value("Start", element.startHour), yEnd: .value("End", element.endHour), width: .ratio(0.99) ) .annotation(position: .overlay, alignment: .topLeading) { item in ZStack { VStack(alignment: .leading, spacing: 0) { // BUG DEMONSTRATION: // This GeometryReader and Rectangle previously filled the BarMark, but in Xcode 27 it does not GeometryReader { geo in Rectangle() .fill(Color.black.opacity(0.15)) .frame(width: geo.size.width, height: geo.size.height) } } .foregroundColor(.white) .font(.caption2) } } } } .chartYScale(domain: 0...24) // Lock the Y-axis to a 24-hour scale } .padding() } } Environment: Xcode 27 beta 1 / iOS 27 beta 1 Reproduces on device and Simulator Worked as expected on iOS 26 and earlier Here's what the issue looks like in our app with zero code changes: iOS 26 iOS 27 I've filed a feedback report (FB23016343) with a sample project attached. Has anyone else hit this, or found a workaround for sizing overlay annotation content to a BarMark in iOS 27? Thanks!
Replies
0
Boosts
0
Views
93
Activity
2w
How to detect backspace in SwiftUI TextField without falling back to UIViewRepresentable?
I'm building a multi-box PIN/OTP input in SwiftUI. In UIKit, I used UITextFieldDelegate to detect backspace presses on an empty field to move focus backward. SwiftUI’s .onChange(of: text) only triggers when text is actually deleted, completely missing backspaces on an already empty field. Is there a pure SwiftUI way to handle this now, or are we still forced to wrap UITextField via UIViewRepresentable?
Replies
1
Boosts
0
Views
103
Activity
2w
Source view disappearing when interrupting a zoom navigation transition
When I use the .zoom transition in a navigation stack, I get a glitch when interrupting the animation by swiping back before it completes. When doing this, the source view disappears. I can still tap it to trigger the navigation again, but its not visible on screen. This seems to be a regression in iOS 26, as it works as expected when testing on iOS 18. Has someone else seen this issue and found a workaround? Is it possible to disable interrupting the transition? Filed a feedback on the issue FB19601591 Screen recording: https://share.icloud.com/photos/04cio3fEcbR6u64PAgxuS2CLQ Example code @State var showDetail = false @Namespace var namespace var body: some View { NavigationStack { ScrollView { showDetailButton } .navigationTitle("Title") .navigationBarTitleDisplayMode(.inline) .navigationDestination(isPresented: $showDetail) { Text("Detail") .navigationTransition(.zoom(sourceID: "zoom", in: namespace)) } } } var showDetailButton: some View { Button { showDetail = true } label: { Text("Show detail") .padding() .background(.green) .matchedTransitionSource(id: "zoom", in: namespace) } } }
Topic: UI Frameworks SubTopic: SwiftUI
Replies
20
Boosts
25
Views
2.4k
Activity
2w
Programatic scroll edge effect for NSScrollView
Just like NSScrollView lets us programmatically set the contentInset in parallel to automaticallyAdjustsContentInsets, I think there should be similar functionality for blurring effect caused by scroll edge effect. I should be able programmatically set it. If the user is manually setting the contentInset then they can simply set a boolean, which when enabled will show edge effect when the scroll document goes outside the area of inset. Eg: scrollView.contentInsets = NSEdgeInsets(top: 100, left: 0, bottom: 0, right: 0) For contentInset like above set by user, they could set edge effect in two ways Automatically: scrollView.enableEdgeEffectOutsideInsets = true // This will apply edge effect based on frame size of contentInsets Programmatically: scrollView.edgeInsetEffectFrame = NSRect...
Topic: UI Frameworks SubTopic: AppKit
Replies
5
Boosts
1
Views
227
Activity
2w
Is there a better way to hide a view in a custom Layout other than placing it off-screen?
I have a custom Layout that places a number of labels for a cell footer in a certain way based on the available width that needs to conditionally hide those views that do not entirely fit anymore (based on some priorities I specify). Currently I simply move the subviews that do not fit anymore off-screen and use clipping to hide them outside the layout, as I did not find an "official" way to hide / exclude a subview from a Layout. Does anyone know a better / nicer way to do this in SwiftUI?
Topic: UI Frameworks SubTopic: SwiftUI
Replies
0
Boosts
0
Views
43
Activity
2w
onChange(of:initial:_:) changes when same value assigned
Overview When calling onChange(of:initial:_:) with initial as true, closure called even when the value assigned is the same as previous value (not just the first time, subsequently too). However when initial value is false it is called only when value changes. Questions Is this a bug? Am I missing something?
Replies
0
Boosts
0
Views
85
Activity
2w
Pass data to an @Observable model
Overview I have a navigation split view. The detail view contains a model now this model depends on id from the parent view. Questions How can I pass data from the parent view and yet create the view in the detail view? Or should I be pass the model from the parent view, but the problem is the parent view needs to persist model. Or is there a better approach?
Replies
0
Boosts
0
Views
52
Activity
2w
about presentationDetents modifier
How do I make the sheet occupy the full screen width and bottom when I customize the height of the sheet using presentationDetents?
Replies
1
Boosts
0
Views
76
Activity
2w
AsyncRenderer stack limit
We've been getting stack overflows in code we don't control, in the background AsyncRenderer thread in a chain of calls to updateInheritedViewAsync. But the stack is less than 200 calls deep, presumably because it's a background thread with a smaller stack limit. Is it possible to adjust AsyncRenderer's stack limit? Or otherwise, what limits should we be aware of to prevent running into this issue? com.apple.SwiftUI.AsyncRenderer: EXC_BAD_ACCESS (code=2, address=0x16f5ebe30) #0 0x000000019c6b4460 in function signature specialization <Arg[3] = Dead> of static SwiftUI.DisplayList.ViewUpdater.Model.merge(item: inout SwiftUI.DisplayList.Item, index: SwiftUI.DisplayList.Index, into: inout SwiftUI.DisplayList.ViewUpdater.Model.State) -> SwiftUI.DisplayList.ViewUpdater.Model.MergedViewRequirements () #1 0x000000019c7c2850 in SwiftUI.DisplayList.ViewUpdater.updateInheritedViewAsync(platform: SwiftUI.DisplayList.ViewUpdater.Platform, oldItem: SwiftUI.DisplayList.Item, oldParentState: Swift.UnsafePointer<SwiftUI.DisplayList.ViewUpdater.Model.State>, newItem: SwiftUI.DisplayList.Item, newParentState: Swift.UnsafePointer<SwiftUI.DisplayList.ViewUpdater.Model.State>) -> Swift.Optional<SwiftUI.Time> () #2 0x000000019c7c3ef0 in SwiftUI.DisplayList.ViewUpdater.updateInheritedViewAsync(platform: SwiftUI.DisplayList.ViewUpdater.Platform, oldItem: SwiftUI.DisplayList.Item, oldParentState: Swift.UnsafePointer<SwiftUI.DisplayList.ViewUpdater.Model.State>, newItem: SwiftUI.DisplayList.Item, newParentState: Swift.UnsafePointer<SwiftUI.DisplayList.ViewUpdater.Model.State>) -> Swift.Optional<SwiftUI.Time> () #3 0x000000019c7c3ef0 in SwiftUI.DisplayList.ViewUpdater.updateInheritedViewAsync(platform: SwiftUI.DisplayList.ViewUpdater.Platform, oldItem: SwiftUI.DisplayList.Item, oldParentState: Swift.UnsafePointer<SwiftUI.DisplayList.ViewUpdater.Model.State>, newItem: SwiftUI.DisplayList.Item, newParentState: Swift.UnsafePointer<SwiftUI.DisplayList.ViewUpdater.Model.State>) -> Swift.Optional<SwiftUI.Time> () #4 0x000000019c7c3ef0 in SwiftUI.DisplayList.ViewUpdater.updateInheritedViewAsync(platform: SwiftUI.DisplayList.ViewUpdater.Platform, oldItem: SwiftUI.DisplayList.Item, oldParentState: Swift.UnsafePointer<SwiftUI.DisplayList.ViewUpdater.Model.State>, newItem: SwiftUI.DisplayList.Item, newParentState: Swift.UnsafePointer<SwiftUI.DisplayList.ViewUpdater.Model.State>) -> Swift.Optional<SwiftUI.Time> () ... #147 0x000000019c7c364c in SwiftUI.DisplayList.ViewUpdater.updateInheritedViewAsync(platform: SwiftUI.DisplayList.ViewUpdater.Platform, oldItem: SwiftUI.DisplayList.Item, oldParentState: Swift.UnsafePointer<SwiftUI.DisplayList.ViewUpdater.Model.State>, newItem: SwiftUI.DisplayList.Item, newParentState: Swift.UnsafePointer<SwiftUI.DisplayList.ViewUpdater.Model.State>) -> Swift.Optional<SwiftUI.Time> () #148 0x000000019c7c2074 in SwiftUI.DisplayList.ViewUpdater.updateAsync(platform: SwiftUI.DisplayList.ViewUpdater.Platform, oldList: SwiftUI.DisplayList, oldParentState: Swift.UnsafePointer<SwiftUI.DisplayList.ViewUpdater.Model.State>, newList: SwiftUI.DisplayList, newParentState: Swift.UnsafePointer<SwiftUI.DisplayList.ViewUpdater.Model.State>) -> Swift.Optional<SwiftUI.Time> () #149 0x000000019c7c1a78 in renderAsync () #150 0x000000019c60fc68 in renderDisplayList () #151 0x000000019c612094 in protocol witness for SwiftUI.ViewGraphRenderHost.renderDisplayList(_: SwiftUI.DisplayList, asynchronously: Swift.Bool, time: SwiftUI.Time, nextTime: SwiftUI.Time, targetTimestamp: Swift.Optional<SwiftUI.Time>, version: SwiftUI.DisplayList.Version, maxVersion: SwiftUI.DisplayList.Version) -> SwiftUI.Time in conformance SwiftUI.ViewGraph : SwiftUI.ViewGraphRenderHost in SwiftUI () #152 0x000000019c7c0dd0 in renderAsync () #153 0x000000019c7be6c8 in SwiftUI.ViewGraphHost.displayLinkTimer(timestamp: SwiftUI.Time, targetTimestamp: SwiftUI.Time, isAsyncThread: Swift.Bool) -> () () #154 0x000000019c7beab8 in SwiftUI.ViewGraphDisplayLink.displayLinkTimer(__C.CADisplayLink) -> () () #155 0x000000019c7be5a8 in @objc SwiftUI.ViewGraphDisplayLink.displayLinkTimer(__C.CADisplayLink) -> () () #156 0x0000000192fdbb24 in CA::Display::DisplayLinkItem::dispatch_ () #157 0x0000000192fb9164 in CA::Display::DisplayLink::dispatch_items () #158 0x0000000192f91870 in display_timer_callback () #159 0x000000019256d4cc in __CFMachPortPerform () #160 0x000000019259d0b0 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ () #161 0x000000019259cfd8 in __CFRunLoopDoSource1 () #162 0x0000000192574c1c in __CFRunLoopRun () #163 0x0000000192573a6c in _CFRunLoopRunSpecificWithOptions () #164 0x0000000190533f54 in -[NSRunLoop(NSRunLoop) runMode:beforeDate:] () #165 0x000000018fb9a51c in -[NSRunLoop(NSRunLoop) run] () #166 0x000000019c7cd5b0 in function signature specialization <Arg[1] = Dead> of static SwiftUI.ViewGraphDisplayLink.asyncThread(arg: Swift.Optional<Any>) -> () () #167 0x000000019c7cd288 in @objc static SwiftUI.ViewGraphDisplayLink.asyncThread(arg: Swift.Optional<Any>) -> () () #168 0x000000018fbf321c in __NSThread__start__ () #169 0x00000001ef0d044c in _pthread_start ()
Topic: UI Frameworks SubTopic: SwiftUI
Replies
2
Boosts
1
Views
140
Activity
2w
How to obtain an app icon regardless of current icon style?
Hey Team, Using NSWorkspace.icon(forFile:) and pointing to an app bundle, the system returns an NSImage with the icon of the app, but in the current style. For example, if the user selected tinted icons in Appearance in System Settings, then any icon I receive back from the API will be tinted using the current accent color. Is there a way to override this and get the original icon? Thanks, Ari
Topic: UI Frameworks SubTopic: AppKit
Replies
3
Boosts
1
Views
148
Activity
2w
Making View's init nonisolated with environment variables
Views with custom nonisolated init fail to compile when using @MainActor-isolated @Environment properties (e.g., \.openURL, \.dismiss). From the Swift 6 migration documentation, it seems encouraged to define inits nonisolated, and it seems base SwiftUI components also have their inits defined as nonisolated (e.g. TimelineView, LazyHStack, etc), which makes sense. How do you achieve marking a SwiftUI View's init as nonisolated when it uses environment variables, without producing the following build error "Main actor-isolated default value of 'self.openURL' cannot be used in a nonisolated initalizer" ? It seems @State variable defined in a view has the ability to be set in a nonisolated init but not @Environment. What mechanism prevents this under the hood ?
Topic: UI Frameworks SubTopic: SwiftUI
Replies
7
Boosts
0
Views
148
Activity
2w
How to get the glassy picker showed at WWD27
In the session "What’s new in SwiftUI", at 02:38 Steven shows various Liquid Glass components, among them, a very pretty interactive glassy Picker. At first I thought this was built into the system and tried everything possible, until to rewatch the presentation and notice this: "On macOS, like on iOS, you can mark Liquid Glass custom elements as "interactive" so they respond more fluidly to user's clicks. And this is optimized to work great with the mouse pointer, so it feels right at home on the Mac." Does anyone have pointers to where one can find a Picker that implements all these system behaviors that folks have come to expect? I have my own version, which is deeply lacking, and so is every other implementation out there that I saw, and I thought sprinkling some "interactive" as instructed would help, but it barely made a dent.
Topic: UI Frameworks SubTopic: SwiftUI
Replies
2
Boosts
0
Views
180
Activity
2w
Best practice for activating a menubar app
Hey Team, I'm developing an app that normally resides in the menu bar and has no Dock icon (activation policy set to accessory. When the user clicks the status icon, and selects 'Settings' in the menu, I change the activation policy to regular, show the window, and activate the app. Since cooperative activation was introduced, the option to ignore all apps when activating was deprecated, so I activate the app without the option. The result is that in 20% of the times, the window doesn't come to the front, or the app is not activated. The user obviously wants this behavior, so what is the proper way to achieve it? Thanks, Ari
Topic: UI Frameworks SubTopic: AppKit
Replies
4
Boosts
3
Views
152
Activity
2w
iOS 27 Swift Charts issues
I get lots of glitches in display of Swift Charts on my iPhone running iOS 27. Works fine on simulator though. Am I the only one?
Replies
2
Boosts
0
Views
95
Activity
2w
Dynamic layouts with multi-line Text views
For a dynamic layout reacting to width changes using ViewThatFits, I need a 2-line Text view where content gets wrapped exactly once, but doesn't get abbreviated. If the text is too long to fit in two lines, ViewThatFits should choose the next layout. I tried to use .lineLimit(2, reservesSpace: true), but then ViewThatFits always takes this layout even when the text content gets too long to fit, so it gets abbreviated with "...", instead of choosing the next layout. How else can I build a layout with a two-line Text, which does signal to ViewThatFits if the space doesn't fit the entire text so it can choose the next layout?
Topic: UI Frameworks SubTopic: SwiftUI
Replies
2
Boosts
0
Views
112
Activity
2w
How to avoid trailing toolbar item re-rendering on child navigation
I have a NavigationStack where every child view except the root has a trailing close button. On each child view transition, the button re-renders itself. Is there a way to fix the button? I saw in the Apple Developer app the behavior I want when registering a lab and the confirmation screen, but I think the implementation is just changing the center content of the view and it isn't pushing a new view to the stack path that has different toolbar items. Root: VStack { Content Next button --> Page 2 } Cancel button leading edge Page 2: VStack { Copy Next button --> page 3 } built in back button leading edge cancel button trailing edge Page 3: VStack { Copy Finish button --> dismisses whole workflow } built in back button leading edge cancel button trailing edge So on page 3, the cancel button is new. I can't figure out how to not have the glass effect animate it in new. I want the 'same' cancel button to be there. This is an oversimplification of a resumable form where the user can cancel (save and resume) at any time. Is there a built in way to have the trailing edge button be fixed? Would moving where the button is defined make a different and expose a way for each child view to propagate upwards if the cancel button should be shown or not? Updated with sample, assumes iOS 18 + 26 code so using .topTrailing not new 'action' placement: import SwiftUI struct Demo: View { @State private var path: [String] = [] var body: some View { NavigationStack(path: $path) { Button("Go") { path.append("Second") } .navigationDestination(for: String.self) { destination in switch destination { case "Second": VStack { Text("Second") Button("Next") { path.append("Third") } } .toolbar { ToolbarItem(placement: .topBarTrailing) { Button("Close", role: .cancel) { path = [] } } } case "Third": VStack { Text("Third") Button("Finish") { path = [] } } .toolbar { ToolbarItem(placement: .topBarTrailing) { Button("Close", role: .cancel) { path = [] } } } default: Text("Undefined") } } } } }
Topic: UI Frameworks SubTopic: SwiftUI
Replies
2
Boosts
0
Views
96
Activity
2w
Correct UIScene Configuration for UISceneAccessory
What is the correct configuration of the Info.plist to get a UISceneAccessory to display on an external monitor? I'm currently getting: Info.plist contained no UIScene configuration dictionary (looking for configuration named "scene-accessory") My Info.plist looks as follows: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>UIApplicationSceneManifest</key> <dict> <key>UIApplicationSupportsMultipleScenes</key> <true/> <key>UISceneConfigurations</key> <dict> <key>UIWindowSceneSessionRoleExternalDisplayNonInteractive</key> <array> <dict> <key>UISceneDelegateClassName</key> <string>$(PRODUCT_MODULE_NAME).AccessorySceneDelegate</string> <key>UISceneConfigurationName</key> <string>scene-accessory</string> </dict> </array> <key>UIWindowSceneSessionRoleApplication</key> <array> <dict> <key>UISceneConfigurationName</key> <string>Default Configuration</string> <key>UISceneDelegateClassName</key> <string>$(PRODUCT_MODULE_NAME).SceneDelegate</string> </dict> </array> </dict> </dict> </dict> </plist> And the view controller scene registration code: class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() let sceneConfiguration = UISceneConfiguration(name: "scene-accessory") let accessory = UISceneAccessory.externalNonInteractive(sceneConfiguration: sceneConfiguration) let registration = registerSceneAccessory(accessory) registration.isEnabled = true } } Thanks!
Topic: UI Frameworks SubTopic: UIKit
Replies
1
Boosts
0
Views
162
Activity
2w