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

AsyncRenderer causes crashes in ForEach when in Swift 6 language mode
Hi! We've recently done a big migration to Swift 6 language mode in our app and are now getting reports of crashes occurring due to closures in our SwiftUI code (most often the view builder in ForEach) not running on the main queue but instead running on the queue com.apple.SwiftUI.AsyncRenderer. One example of a call stack (ScheduleListView is our view that is in Swift 6 mode): Thread 16 #0 (null) in _dispatch_assert_queue_fail () #1 (null) in dispatch_assert_queue$V2.cold.1 () #2 (null) in dispatch_assert_queue () #3 (null) in swift_task_isCurrentExecutorWithFlagsImpl(swift::SerialExecutorRef, swift::swift_task_is_current_executor_flag) () #4 (null) in closure #2 in closure #1 in closure #1 in ScheduleListView.body.getter () #5 (null) in closure #1 in ForEachState.item(at:offset:) () #6 (null) in partial apply for closure #1 in ForEachState.item(at:offset:) () #8 (null) in partial apply for closure #1 in _withObservation<A>(do:) () .... (We have many other crashes with similar crash reports but in other views) Has anybody else run into something similar? Is there anything (other than simply reverting to Swift 5 mode again) that we can do to fix or at least reduce the amount of crashes? We're having a hard time finding anything out of the ordinary that we're doing in our views. Regards
Topic: UI Frameworks SubTopic: SwiftUI
3
3
282
2w
.glassProminent toolbar buttons are glitchy in iOS 26.1 RC
I've adopted the new .glassProminent button style for primary/confirmation actions in the toolbar. Starting around beta 3 or 4 of iOS 26.1, these buttons started glitching: When navigating to a view, the button is initially untinted, and then the tint abruptly appears after a 1 second delay. This is still the case in the 26.1 release candidate, and it is also affecting Apple's own apps. This new style is one of the defining characteristics of the new design system, so I find it hard to believe that Apple hasn't noticed this regression, which leads me to wonder if I might be doing something wrong or if this is specific to my device (12 mini). Is this the correct way to achieve the effect: ToolbarItem(placement: .confirmationAction) { Button("button_submit", action: submitMessage) .buttonStyle(.glassProminent) .tint(Color.blue) } The same glitch occurs if I use .primaryAction, and it also occurs even if I remove the .tint modifier. It seems to be a problem with .glassProminent. It looks really janky, so now I feel like I need to pull out all my .glassProminent toolbar buttons in preparation for iOS 26.1's release.
Topic: UI Frameworks SubTopic: SwiftUI
2
0
91
2w
Detect link taps in the AttributedString version of TextEditor?
iOS 26 added an AttributedString version of TextEditor. It can display links but I have no idea how to detect when a user taps them. This is possible when using a Text element and the openURL environment modifier, but this doesn't seem to work with TextEditor? e.g. struct ContentView: View { var text: AttributedString { var attributedString = AttributedString("Link") attributedString.link = URL(string: "https://www.apple.com") return attributedString } var body: some View { TextEditor(text: .constant(text)) .environment(\.openURL, OpenURLAction { url in // This is not called. print(url) return .handled }) } } Any ideas?
Topic: UI Frameworks SubTopic: SwiftUI
1
0
63
2w
SwiftUI state is maddening
I honestly thought I was getting somewhere with this, but alas, no. Every time I do anything in my List of ItemRows it jumps back to the top. Here's the setup: DataService.swift: final class DataService { static let shared = DataService() private init() {} let coreData: CoreData = CoreData() let modelData: ModelData = ModelData() } ModelData.swift: @Observable class ModelData: ObservableObject { var allItems: [ItemDetails] var standardItems: [ItemDetails] var archivedItems: [ItemDetails] init() { allItems = [] standardItems = [] archivedItems = [] } func getInitialData() { // Get all items, then split them into archived and non-archived sets, because you can't use `.filter` in a view... allItems = dataService.coreData.getAllItems() standardItems.append(contentsOf: allItems.filter { !$0.archived }) archivedItems.append(contentsOf: allItems.filter { $0.archived }) } } MainApp.swift: // Get access to the data; this singleton is a global as non-view-based functions, including the `Scene`, need to access the model data let dataService: DataService = DataService.shared @main struct MainApp: App { // Should this be @ObservedObject or @StateObject? @ObservedObject private var modelData: ModelData = dataService.modelData // I would use @StateObject if the line was... //@StateObject private var modelData: ModelData = ModelData() // right? // But then I couldn't use modelData outside of the view hierarchy var body: some Scene { WindowGroup { ZStack { MainView() .environment(modelData) } } .onAppear { modelData.getInitialData() } } } MainView.swift: struct MainView: View { @Environment(ModelData.self) private var modelData: ModelData var body: some View { ... ForEach(modelData.standardItems) { item in ItemRow(item) } ForEach(modelData.archivedItems) { item in ItemRow(item) } } } ItemRow.swift: struct ItemRow: View { @Environment(\.accessibilityDifferentiateWithoutColor) private var accessibilityDifferentiateWithoutColor var item: ItemDetails @State private var showDeleteConfirmation: Bool = false var body: some View { // Construct the row view // `accessibilityDifferentiateWithoutColor` is used within the row to change colours if DWC is enabled, e.g. use different symbols instead of different colours for button images. // Add the .leftSwipeButtons, .rightSwipeButtons, and .contextMenu // Add the .confirmationDialog for when I want to ask for confirmation before deleting an item } } Now, the problems: Swipe an item row, tap one of the buttons, e.g. edit, and the list refreshes and jumps back to the top. In the console I see: ItemRow: @self, @identity, _accessibilityDifferentiateWithoutColor changed. Why did accessibilityDifferentiateWithoutColor change? The setting in Settings > Accessibility > Display & Text Size has not been changed, so why does the row's view think it changed? With a .confirmationDialog attached to the end of the ItemRow (as seen in the code above), if I swipe and tap the delete button the list refreshes and jumps back to the top again. In the console I see: ItemRow: @self, @identity, _accessibilityDifferentiateWithoutColor, _showDeleteConfirmation changed. Right, it changed for the one row that I tapped the button for. Why does every row get redrawn? I already had to shift from using the colorScheme environment variable to add new asset colours with light and dark variants to cover this, but you can't do that with DWC. Honestly, managing state in SwiftUI is a nightmare. I had zero problems until iOS 26 started removing one or two rows when I scrolled, and the fix for that - using @Statebject/@ObservedObject - has introduced multiple further annoying, mind-bending problems, and necessitated massive daily refactorings. And, of course, plenty of my time islost trying to figure out where a problem is in the code because "The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions"...
7
0
211
2w
NSISSparseVectorAddTermWithPlaceValueCoefficientStartingIndex.cold.1 crash
Hi, We began to get this new crash in codes that exist years ago from our recent released version, it crashed after a view removed itself from superview. We tried to look at the assembly code of NSISSparseVectorAddTermWithPlaceValueCoefficientStartingIndex, find out that d0 <= 0 would branch to NSISSparseVectorAddTermWithPlaceValueCoefficientStartingIndex.cold.1. We believe that it's related with Autolayout, but setting a negative value for width or height constraints can't reproduce this crash. Here is the crash log Exception Type: NSInternalInconsistencyException Invalid parameter not satisfying: placeValue > 0 Exception Codes: fault addr: (null) Crashed Thread: 0 0 CoreFoundation ___exceptionPreprocess + 164 1 libobjc.A.dylib _objc_exception_throw + 88 2 Foundation -[NSMutableDictionary(NSMutableDictionary) initWithContentsOfFile:] + 0 3 CoreAutoLayout NSISSparseVectorAddTermWithPlaceValueCoefficientStartingIndex.cold.1 + 100 4 CoreAutoLayout _NSISSparseVectorAddTermWithPlaceValueCoefficientStartingIndex + 848 5 CoreAutoLayout _NSISSparseVectorAddVectorTimesScalar + 72 6 CoreAutoLayout -[NSISObjectiveLinearExpression replaceVar:withExpression:processVarNewToReceiver:processVarDroppedFromReceiver:] + 200 7 CoreAutoLayout ____substituteOutAllOccurencesOfBodyVar_block_invoke + 504 8 CoreAutoLayout __substituteOutAllOccurencesOfBodyVar + 340 9 CoreAutoLayout __pivotToMakeColNewHeadOfRow + 960 10 CoreAutoLayout -[NSISEngine removeConstraintWithMarker:] + 748 11 CoreAutoLayout -[NSLayoutConstraint _removeFromEngine:] + 140 12 UIKitCore ___57-[UIView(AdditionalLayoutSupport) _switchToLayoutEngine:]_block_invoke + 164 13 CoreAutoLayout -[NSISEngine withBehaviors:performModifications:] + 84 14 UIKitCore -[UIView(AdditionalLayoutSupport) _switchToLayoutEngine:] + 212 15 UIKitCore ___57-[UIView(AdditionalLayoutSupport) _switchToLayoutEngine:]_block_invoke_2 + 148 16 UIKitCore ___57-[UIView(AdditionalLayoutSupport) _switchToLayoutEngine:]_block_invoke + 544 17 CoreAutoLayout -[NSISEngine withBehaviors:performModifications:] + 84 18 UIKitCore -[UIView(AdditionalLayoutSupport) _switchToLayoutEngine:] + 212 19 UIKitCore ___45-[UIView(Hierarchy) _postMovedFromSuperview:]_block_invoke + 84 20 CoreAutoLayout -[NSISEngine withBehaviors:performModifications:] + 84 21 UIKitCore -[UIView _postMovedFromSuperview:] + 512 22 UIKitCore ___UIViewWasRemovedFromSuperview + 136 23 UIKitCore -[UIView(Hierarchy) removeFromSuperview] + 244 Assembly of NSISSparseVectorAddTermWithPlaceValueCoefficientStartingIndex CoreAutoLayout`NSISSparseVectorAddTermWithPlaceValueCoefficientStartingIndex: -> 0x1ec1a2124 <+0>: pacibsp 0x1ec1a2128 <+4>: stp d11, d10, [sp, #-0x60]! 0x1ec1a212c <+8>: stp d9, d8, [sp, #0x10] 0x1ec1a2130 <+12>: stp x24, x23, [sp, #0x20] 0x1ec1a2134 <+16>: stp x22, x21, [sp, #0x30] 0x1ec1a2138 <+20>: stp x20, x19, [sp, #0x40] 0x1ec1a213c <+24>: stp x29, x30, [sp, #0x50] 0x1ec1a2140 <+28>: add x29, sp, #0x50 0x1ec1a2144 <+32>: mov x19, x1 0x1ec1a2148 <+36>: fmov d9, d2 0x1ec1a214c <+40>: fmov d10, d1 0x1ec1a2150 <+44>: fmov d8, d0 0x1ec1a2154 <+48>: mov x20, x0 0x1ec1a2158 <+52>: fcmp d0, #0.0 0x1ec1a215c <+56>: b.le 0x1ec1a2470 ; <+844> 0x1ec1a2160 <+60>: fcmp d10, #0.0 0x1ec1a2164 <+64>: adrp x8, 112778 .... 0x1ec1a2468 <+836>: ldp d11, d10, [sp], #0x60 0x1ec1a246c <+840>: retab 0x1ec1a2470 <+844>: bl 0x1ec1cac18 ; NSISSparseVectorAddTermWithPlaceValueCoefficientStartingIndex.cold.1 0x1ec1a2474 <+848>: b 0x1ec1a2160 ; <+60>
0
0
128
2w
Watchface Sharing Fails in TestFlight/AppStore on iOS/watchOS 26 (Works in Dev Builds)
Hello everyone, I am facing a critical and blocking issue regarding watchface sharing on iOS/watchOS 26 and would appreciate any immediate guidance or updates from the community or Apple. The Problem: We are unable to share watchfaces containing any complications from our app in TestFlight and App Store distribution environments. The operation fails with an error indicating the app and complications are unavailable. However, the exact same functionality works perfectly in all development builds (both Debug and Release schemes). This issue was not present on iOS/watchOS 18. We have testing, including: Successfully sharing the watchface in development environments. The failure occurs consistently across TestFlight and App Store builds. Exporting the watchface configuration from a TestFlight/AppStore build on iOS, transferring it to a paired watch, and finding it still shows as "Unavailable". We suspect this may be related to the dual-target architecture of Watch apps. Any guidance or updates would be greatly appreciated. Thank you for your time and support!
2
0
121
2w
Critical Bug in iOS 18.1 RC and watchOS 11.1 RC - WidgetKit Complications Not Syncing
I've encountered a major issue with the iOS 18.1 RC and watchOS 11.1 RC. It appears that complications running on WidgetKit cannot be synced as .watchface to these new release candidates. The error message indicates that "the Watch Faces app and complication are not available," which is affecting all apps utilizing WidgetKit. This issue renders all WidgetKit-based complications unusable on watchOS 11.1 RC. It’s a serious problem for those of us who rely on these complications for our apps and for users expecting consistent functionality. APPLE, PLEASE FIX THIS ISSUE ASAP! This bug is a significant setback for developers and users alike, and any guidance or updates would be greatly appreciated.
4
0
918
2w
Drag and Drop Question
This example is based on the latest version of Swift 6.2 for macOS. I have several classes that cannot conform to Codable for various reasons. This, unfortunately, prevents me from using Transferable. If I serialize a class instance into a Data blob and use that for drag-and-drop, it works perfectly — the drag operation succeeds. However, the destination has no way to distinguish between different types of Data blobs. All I’d need is a way to specify a unique identifier and type that I could reference in the drop handler to determine what kind of object I’m working with. Being restricted to Transferable feels quite limiting when your data models can’t conform to Codable. It’s honestly frustrating. Has anyone else run into this issue? Is there a reliable workaround? I tried creating a Transferable wrapper like this: struct CustomObjectTransfer: Codable, Transferable { var data: Data static var transferRepresentation: some TransferRepresentation { // Cannot use '.myGreatSettings' because Main actor–isolated static property 'myGreatSettings' cannot be referenced from a nonisolated context CodableRepresentation(contentType: .init(exportedAs: "com.yourProject.settings")) } } extension UTType { static let myGreatSettings: UTType = UTType("com.yourProject.settings")! } In my list view .draggable ( CustomObjectTransfer(data: myObjectData) ) The UI correctly recognizes the item as draggable. If I misspell the exportedAs identifier, it even throws an error, confirming that the exported type is being recognized by the system. However, the drop destination completely ignores this type: .dropDestination(for: CustomObjectTransfer.self) { items, location in dump(items) return true }isTargeted: { isTargeted in myDestinationIsTargeted = isTargeted } If I switch to using Data.self directly — wrapping the original object data manually — everything works. I can deserialize and validate the data as needed. The problem arises when handling multiple custom drag types. The drop target accepts any data, regardless of its intended type. You only find out the actual type after the drop occurs, during validation — which is too late. By then, isTargeted has already turned true, making the drop appear valid to the user when it actually isn’t. Again anyone else feel this pain? Or is there a workaround that I am missing?
4
0
140
2w
Carousel Flicker
Hi, I've created an carousel using an Tabview component and it is divided in pages, each page has 7 items. Now we wan't to load the carousel page by page, but whenever I updated the list which Tabview uses to render, it flickers because it rerenders previous elements. I've tried to use a scroll view for this but this app is for Vision Pro and I added some 3D transformations (position/rotation) to the cards from the tabview and when I added this in the scrollview they becom unclickable. Do you have any sugestions what can I do? Bellow is a sample of the code, I put [items] just to suggest there is a list. VStack (spacing: 45) { TabView(selection: $navigationModel.carouselSelectedPage) { let orderedArtist = [items] let numberOfPages = Int((Double(orderedArtist.count) / Double(cardsPerPage)).rounded(.up)) if(numberOfPages != 1){ Spacer().tag(-1) } ForEach(0..<numberOfPages, id: \.self) { page in LazyHStack(alignment: .top, spacing: 16){ ForEach(0..<cardsPerPage, id: \.self) { index in if(page * cardsPerPage + index < orderedArtist.count){ let item = orderedArtist[page * cardsPerPage + index] GeometryReader{proxy in
2
0
380
2w
SwiftUI List with Geometry header behavior changed after building app with Xcode 26
We have a custom implementation of what we call a “Scrollable Header” in our app. After building with Xcode 26, we’ve observed a change in behavior with the List component. The issue can be seen in the attached GIF: As the user scrolls up, the header is expected to collapse smoothly, and it does—until the moment the next list item becomes visible. At that point, the header collapses prematurely, without any apparent reason. We’ve identified that this behavior occurs after the list’s data-fetching logic runs, which loads additional items as the user scrolls. Below is the ViewModifier responsible for handling the collapsing header logic: @available(iOS 18.0, *) public struct L3CollapseHeaderIOS18: ViewModifier { private let minHeight: Double = 0 private let expandedHeight: CGFloat private let L3Height = 44.0 private let isViewVisible: Bool @Binding private var currentHeight: CGFloat @State private var lastOffset: ScrollOffsetInfo = ScrollOffsetInfo(offset: 0.0, offsetToBottom: 0.0, scrollableContent: 0.0) init(currentHeight: Binding<CGFloat>, expectedHeight: CGFloat, isViewVisible: Bool) { self._currentHeight = currentHeight self.expandedHeight = expectedHeight self.isViewVisible = isViewVisible } public func body(content: Content) -> some View { content .onScrollGeometryChange(for: ScrollOffsetInfo.self, of: { geometry in if isViewVisible { return ScrollOffsetInfo(offset: geometry.contentOffset.y, offsetToBottom: (geometry.contentSize.height) - (geometry.contentOffset.y + geometry.containerSize.height), scrollableContent: geometry.contentSize.height - geometry.containerSize.height) } else { return lastOffset } }, action: { oldValue, newValue in if isViewVisible { expandOrCollapseHeader(oldValue: oldValue, newValue: newValue) } }) } private func expandOrCollapseHeader(oldValue: ScrollOffsetInfo, newValue: ScrollOffsetInfo) { let oldScrollableContent = round(oldValue.scrollableContent) let newScrollableContent = round(newValue.scrollableContent) print("@@ scrollable content: \(newScrollableContent), old value: \(oldScrollableContent)") if newScrollableContent != oldScrollableContent {/*abs(newValue.offset) - abs(oldValue.offset) > 80*/ return } let isInitialPosition = newValue.offset == 0 && lastOffset.offset == 0 let isTryingToBounceUp = newValue.offset < 0 let isTryingToBounceDown = newValue.offsetToBottom < 0 // As the header collapses, the scrollable content decreases its size let remainingHeaderSpaceVisible = expandedHeight - currentHeight // remainingHeaderSpaceVisible is summed to know the exact scrollableContent size let isScrollableContentSmallToAnimate = (newValue.scrollableContent + remainingHeaderSpaceVisible) < (expandedHeight * 2 + currentHeight) if isInitialPosition || isScrollableContentSmallToAnimate { expandHeader(0) return } let scrollDirection = scrollDirection(newValue, oldOffset: oldValue) switch scrollDirection { case .up(let value): if isTryingToBounceUp { expandHeader(0) return } print("@@ will collapse with value: \(value)") collapseHeader(value) case .down(let value): if isTryingToBounceDown { collapseHeader(0) return } print("@@ will expand with value: \(value)") expandHeader(value) case .insignificant: return } } private func expandHeader(_ value: CGFloat) { currentHeight = min(68.0, currentHeight - value) } private func collapseHeader(_ value: CGFloat) { currentHeight = max(0, currentHeight - value) } private func scrollDirection(_ currentOffset: ScrollOffsetInfo, oldOffset: ScrollOffsetInfo) -> ScrollDirection { let scrollOffsetDifference = abs(currentOffset.offset) - abs(oldOffset.offset) print("@@ currentOffset: \(currentOffset.offset), oldOffset: \(oldOffset.offset), difference: \(scrollOffsetDifference)") let status: ScrollDirection = scrollOffsetDifference > 0 ? .up(scrollOffsetDifference) : .down(scrollOffsetDifference) lastOffset = currentOffset return status } enum ScrollDirection { case up(CGFloat) case down(CGFloat) case insignificant } } public struct ScrollOffsetInfo: Equatable { public let offset: CGFloat public let offsetToBottom: CGFloat public let scrollableContent: CGFloat } public struct ScrollOffsetInfoPreferenceKey: PreferenceKey { public static var defaultValue: ScrollOffsetInfo = ScrollOffsetInfo(offset: 0, offsetToBottom: 0, scrollableContent: 0) public static func reduce(value: inout ScrollOffsetInfo, nextValue: () -> ScrollOffsetInfo) { } } We use this ViewModifier to monitor updates to the List’s frame via the onScrollGeometryChange method. From our investigation (see the screenshot below), it appears that onScrollGeometryChange is triggered just before the content size updates. The first event we receive corresponds to the view’s offset, and only nanoseconds later do we receive updates about the content’s scrollable height. I’ll share the code for the List component using this modifier in the comments (it exceeded the character limit here). Can anyone help us understand why this change in behavior occurs after building with Xcode 26? Thanks in advance for any insights.
3
2
128
2w
UtilityWindow can't read @FocusedValue of main scene
According to the UtilityWindow documentation: • They receive FocusedValues from the focused main scene in an application, similar to commands in the main menu, which can be used to display information on the active content as the user focuses on different scenes. This makes me think that any UtilityWindow, even across Scenes, should always receive @FocusedValues from the currently focused window of any scene. However, the following code doesn't quite work: @Observable class Info: Identifiable { let id = UUID() } struct ExampleApp: App { var body: some Scene { WindowGroup { ContentView() // Inside, it uses .focusedSceneValue(info) } UtilityWindow("Test") { UtilityWindowContent() } } } struct UtilityWindowContent: View { @FocusedValue(Info.self) var info var body: some View { Text(info?.id ?? "<nil>") // This always shows "<nil>" } } Here's some annotated screenshots of what's happening in a project: Menu bar commands do work with the same setup: As a workaround, attempting to use @FocusedValue in the App struct works, but as a result, the value appears to instantiate multiple times in the background, and they re-instantiate with every focus change. The @FocusedValue variable gets the correct instance, but it's needlessly initializing others in the background. This is on macOS 26.0 Tahoe Beta 8 (25A5349a).
1
0
137
2w
Invalid parameter not satisfying: parentEnvironment != nil
Since the beta releases of iPadOS 26 we have been having some crashes about Invalid parameter not satisfying: parentEnvironment != nil We got to contact a couple of users and we found out that the crash appears when entering a screen in a UINavigationController with the iPad device connected to a Magic Keyboard. If the device is not connected to the keyboard then nothing happens and everything works ok. From our end we haven't managed to reproduce the crash so I am pasting part of the stacktrace if it can be of any help. 3 UIKitCore 0x19dfd2e14 -[_UIFocusContainerGuideFallbackItemsContainer initWithParentEnvironment:childItems:] + 224 (_UIFocusContainerGuideFallbackItemsContainer.m:23) 4 UIKitCore 0x19dae3108 -[_UIFocusContainerGuideImpl _searchForFocusRegionsInContext:] + 368 (_UIFocusGuideImpl.m:246) 5 UIKitCore 0x19db28498 -[_UIFocusMapSnapshot addRegionsInContainer:] + 2720 (_UIFocusMapSnapshot.m:531) 6 UIKitCore 0x19db28900 -[_UIFocusMapSnapshot addRegionsInContainers:] + 160 (_UIFocusMapSnapshot.m:545) 7 UIKitCore 0x19d1313dc _UIFocusRegionSearchContextSearchForFocusRegionsInEnvironment + 632 (_UIFocusRegion.m:143) 8 UIKitCore 0x19db1d244 -[_UIFocusRegionContainerProxy _searchForFocusRegionsInContext:] + 140 (_UIFocusRegionContainerProxy.m:184) 9 UIKitCore 0x19db28498 -[_UIFocusMapSnapshot addRegionsInContainer:] + 2720 (_UIFocusMapSnapshot.m:531) 10 UIKitCore 0x19d1320fc _UIFocusItemContainerAddChildItemsInContextWithOptions + 596 (UIFocusItemContainer.m:183) 11 UIKitCore 0x19d131b98 _UIFocusRegionSearchContextAddChildItemsInEnvironmentContainer + 648 (_UIFocusRegion.m:108) 12 UIKitCore 0x19d131398 _UIFocusRegionSearchContextSearchForFocusRegionsInEnvironment + 564 (_UIFocusRegion.m:140) 13 UIKitCore 0x19db1d244 -[_UIFocusRegionContainerProxy _searchForFocusRegionsInContext:] + 140 (_UIFocusRegionContainerProxy.m:184) 14 UIKitCore 0x19db28498 -[_UIFocusMapSnapshot addRegionsInContainer:] + 2720 (_UIFocusMapSnapshot.m:531) 15 UIKitCore 0x19d1320fc _UIFocusItemContainerAddChildItemsInContextWithOptions + 596 (UIFocusItemContainer.m:183) 16 UIKitCore 0x19d131b98 _UIFocusRegionSearchContextAddChildItemsInEnvironmentContainer + 648 (_UIFocusRegion.m:108) 17 UIKitCore 0x19d131398 _UIFocusRegionSearchContextSearchForFocusRegionsInEnvironment + 564 (_UIFocusRegion.m:140) 18 UIKitCore 0x19db1d244 -[_UIFocusRegionContainerProxy _searchForFocusRegionsInContext:] + 140 (_UIFocusRegionContainerProxy.m:184) 19 UIKitCore 0x19db28498 -[_UIFocusMapSnapshot addRegionsInContainer:] + 2720 (_UIFocusMapSnapshot.m:531) 20 UIKitCore 0x19d1320fc _UIFocusItemContainerAddChildItemsInContextWithOptions + 596 (UIFocusItemContainer.m:183) 21 UIKitCore 0x19d131b98 _UIFocusRegionSearchContextAddChildItemsInEnvironmentContainer + 648 (_UIFocusRegion.m:108) 22 UIKitCore 0x19d131398 _UIFocusRegionSearchContextSearchForFocusRegionsInEnvironment + 564 (_UIFocusRegion.m:140) 23 UIKitCore 0x19db1d244 -[_UIFocusRegionContainerProxy _searchForFocusRegionsInContext:] + 140 (_UIFocusRegionContainerProxy.m:184) 24 UIKitCore 0x19db28498 -[_UIFocusMapSnapshot addRegionsInContainer:] + 2720 (_UIFocusMapSnapshot.m:531) 25 UIKitCore 0x19d1320fc _UIFocusItemContainerAddChildItemsInContextWithOptions + 596 (UIFocusItemContainer.m:183) 26 UIKitCore 0x19d131b98 _UIFocusRegionSearchContextAddChildItemsInEnvironmentContainer + 648 (_UIFocusRegion.m:108) 27 UIKitCore 0x19d131398 _UIFocusRegionSearchContextSearchForFocusRegionsInEnvironment + 564 (_UIFocusRegion.m:140) 28 UIKitCore 0x19db1d244 -[_UIFocusRegionContainerProxy _searchForFocusRegionsInContext:] + 140 (_UIFocusRegionContainerProxy.m:184) 29 UIKitCore 0x19db28498 -[_UIFocusMapSnapshot addRegionsInContainer:] + 2720 (_UIFocusMapSnapshot.m:531) 30 UIKitCore 0x19d1320fc _UIFocusItemContainerAddChildItemsInContextWithOptions + 596 (UIFocusItemContainer.m:183) 31 UIKitCore 0x19d131b98 _UIFocusRegionSearchContextAddChildItemsInEnvironmentContainer + 648 (_UIFocusRegion.m:108) 32 UIKitCore 0x19d131398 _UIFocusRegionSearchContextSearchForFocusRegionsInEnvironment + 564 (_UIFocusRegion.m:140) 33 UIKitCore 0x19db1d244 -[_UIFocusRegionContainerProxy _searchForFocusRegionsInContext:] + 140 (_UIFocusRegionContainerProxy.m:184) 34 UIKitCore 0x19db28498 -[_UIFocusMapSnapshot addRegionsInContainer:] + 2720 (_UIFocusMapSnapshot.m:531) 35 UIKitCore 0x19d1320fc _UIFocusItemContainerAddChildItemsInContextWithOptions + 596 (UIFocusItemContainer.m:183) 36 UIKitCore 0x19d131b98 _UIFocusRegionSearchContextAddChildItemsInEnvironmentContainer + 648 (_UIFocusRegion.m:108) 37 UIKitCore 0x19d131398 _UIFocusRegionSearchContextSearchForFocusRegionsInEnvironment + 564 (_UIFocusRegion.m:140) 38 UIKitCore 0x19db1d244 -[_UIFocusRegionContainerProxy _searchForFocusRegionsInContext:] + 140 (_UIFocusRegionContainerProxy.m:184) 39 UIKitCore 0x19db28498 -[_UIFocusMapSnapshot addRegionsInContainer:] + 2720 (_UIFocusMapSnapshot.m:531) 40 UIKitCore 0x19d132e08 -[_UIFocusMapSnapshot _capture] + 424 (_UIFocusMapSnapshot.m:403) 41 UIKitCore 0x19db2675c -[_UIFocusMapSnapshot _initWithSnapshotter:mapArea:searchArea:] + 476 (_UIFocusMapSnapshot.m:171) 42 UIKitCore 0x19d130dcc -[_UIFocusMapSnapshotter captureSnapshot] + 192 (_UIFocusMapSnapshotter.m:137) 43 UIKitCore 0x19db2045c -[_UIFocusMap _inferredDefaultFocusItemInEnvironment:] + 136 (_UIFocusMap.m:168) 44 UIKitCore 0x19daffd2c -[_UIFocusEnvironmentPreferenceEnumerationContext _inferPreferencesForEnvironment:] + 140 (_UIFocusEnvironmentPreferenceEnumerator.m:313) 45 UIKitCore 0x19d127ab4 -[_UIFocusEnvironmentPreferenceEnumerationContext _resolvePreferredFocusEnvironments] + 104 (_UIFocusEnvironmentPreferenceEnumerator.m:250) 46 UIKitCore 0x19d127394 -[_UIFocusEnvironmentPreferenceEnumerationContext preferredEnvironments] + 36 (_UIFocusEnvironmentPreferenceEnumerator.m:184) 47 UIKitCore 0x19d126e94 _enumeratePreferredFocusEnvironments + 400 (_UIFocusEnvironmentPreferenceEnumerator.m:503)
0
1
58
2w
UIKit.ButtonBarButtonVisualProvider not key value coding-compliant for the key _titleButton
After updating to Xcode 26 my XCUITests are now failing as during execution exceptions are being raised and caught by my catch all breakpoint These exceptions are only raised during testing, and seem to be referencing some private internal property. It happens when trying to tap a button based off an accessibilityIdentifier e.g. accessibilityIdentifier = "tertiary-button" ... ... app.buttons["tertiary-button"].tap() The full error is: Thread 1: "[<UIKit.ButtonBarButtonVisualProvider 0x600003b4aa00> valueForUndefinedKey:]: this class is not key value coding-compliant for the key _titleButton." Anyone found any workarounds or solutions? I need to get my tests running on the liquid glass UI
1
3
129
2w
Button Glass Style Incorrect in Sheet + ScrollView on Mac Catalyst 26
Hi everyone! I've encountered an issue when using Sheet + ScrollView on Mac Catalyst: the buttons in the toolbar appear with an abnormal gray color. import SwiftUI struct ContentView: View { var body: some View { VStack { } .sheet(isPresented: .constant(true)) { Sheet() } } } struct Sheet: View { var body: some View { NavigationStack { ScrollView { // <-- no issue if use List } .toolbar { Button(action: {}) { // <-- 👀 weird gray color Image(systemName: "checkmark") } } } } } Steps to Reproduce: On macOS 26.0 beta 9, use Xcode 26.0 beta 7 to create an iOS project and enable Mac Catalyst. Paste the code above. Select the Mac Catalyst scheme and run the project. The buttons in the toolbar show a strange gray appearance. If you change the ScrollView to a List in the code, the issue does not occur. FB20120285
2
0
343
2w
iOS 26: UIAlertController appears at the top of the screen
When displaying a full-screen model from a view that has constraints with KeyboardLayoutGuide, and then displaying a UIAlertController after closing that modal, the UIAlertController appears at the top of the screen. This behavior appears only on iOS 26 devices with external keyboard devices (or simulators with "Connect Hardware Keyboard" setting on.) iPhone 16 (simulator), iOS 26.0 iPhone 16 (simulator), iOS 18.5 Here's the sample code reproducing this issue: import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. self.view.keyboardLayoutGuide.topAnchor.constraint(equalToSystemSpacingBelow: self.view.bottomAnchor, multiplier: 0).isActive = true let vc = UIViewController() vc.modalPresentationStyle = .fullScreen vc.view.backgroundColor = .white self.present(vc, animated: true) { [weak self] in vc.dismiss(animated: true) { [weak self] in let alert = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet) alert.addAction(UIAlertAction(title: "OK", style: .default)) alert.addAction(UIAlertAction(title: "CANCEL", style: .cancel)) self?.present(alert, animated: true) } } } } Environment: Xcode 26.0.1 (17A400)
Topic: UI Frameworks SubTopic: UIKit
1
0
203
2w
DefaultToolbarItem search in bottom bar
When using: DefaultToolbarItem(kind: .search, placement: .bottomBar) on iOS 26.1 the search item is suddenly expanded and has a label, while on iOS 26 it was an icon, like any other toolbar item. Is that intentional? How can we make it to only show an icon? (sumbitted FB20868106)
Topic: UI Frameworks SubTopic: SwiftUI
1
0
87
2w
Expandable cell in List View shows slowly after swiping to delete it
If the cell is expandable in List View, it will show slowly after deletion swipe. the image shows how it looks like when this issue happens and it should be easy to reproduce with this sample codes // Model for list items struct ListItem: Identifiable { let id = UUID() let title: String let createdDate: Date let description: String } struct ExpandableListView: View { // Sample constant data private let items: [ListItem] = [ ListItem( title: "First Item", createdDate: Date().addingTimeInterval(-86400 * 5), description: "This is a detailed description for the first item. It contains two lines of text to show when expanded." ), ListItem( title: "Second Item", createdDate: Date().addingTimeInterval(-86400 * 3), description: "This is a detailed description for the second item. It provides additional information about this entry." ), ListItem( title: "Third Item", createdDate: Date().addingTimeInterval(-86400 * 1), description: "This is a detailed description for the third item. Tap to expand and see more details here." ), ListItem( title: "Fourth Item", createdDate: Date(), description: "This is a detailed description for the fourth item. It shows comprehensive information when tapped." ) ] // Track which item is currently selected/expanded @State private var selectedItemId: UUID? = nil var body: some View { NavigationView { List { ForEach(items) { item in ExpandableCell( item: item, isExpanded: selectedItemId == item.id ) { // Handle tap - toggle selection withAnimation(.easeInOut(duration: 0.3)) { if selectedItemId == item.id { selectedItemId = nil } else { selectedItemId = item.id } } } } .onDelete { indexSet in for index in indexSet { print("delete \(items[index].title)") } } } .navigationTitle("Items") } } } struct ExpandableCell: View { let item: ListItem let isExpanded: Bool let onTap: () -> Void private var dateFormatter: DateFormatter { let formatter = DateFormatter() formatter.dateStyle = .medium formatter.timeStyle = .short return formatter } var body: some View { VStack(alignment: .leading, spacing: 8) { // Always visible: Title and Date HStack { VStack(alignment: .leading, spacing: 4) { Text(item.title) .font(.headline) .foregroundColor(.primary) Text(dateFormatter.string(from: item.createdDate)) .font(.caption) .foregroundColor(.secondary) } Spacer() // Chevron indicator Image(systemName: isExpanded ? "chevron.up" : "chevron.down") .foregroundColor(.secondary) .font(.caption) } // Expandable: Description (2 lines) if isExpanded { Text(item.description) .font(.body) .foregroundColor(.secondary) .lineLimit(2) .fixedSize(horizontal: false, vertical: true) .transition(.opacity.combined(with: .move(edge: .top))) .padding(.top, 4) } } .padding(.vertical, 8) .contentShape(Rectangle()) .onTapGesture { onTap() } } } #Preview { ExpandableListView() }
3
0
99
2w