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

MenuBarExtra with .window style: .onHover modifier doesn't work on macOS 26 Tahoe
List { Text("ITEM 1") .onHover(perform: { hovering in debugPrint("hovering: ", hovering) }) .help("ITEM 1") Text("ITEM 2") .onHover(perform: { hovering in debugPrint("hovering: ", hovering) }) .help("ITEM 2") Text("ITEM 3") .onHover(perform: { hovering in debugPrint("hovering: ", hovering) }) .help("ITEM 3") } .fixedSize(horizontal: false, vertical: true) .frame(maxHeight: 200) } Hello everyone!!! Considering the snippet above, seems like the onHover action, including help modifiers, doesn't work for the elements of a List, on macOS Tahoe. The situation changes using a ScrollView embedding a LazyVStack, or disabling Liquid Glass from the info plist, so my guess is that the new Liquid Glass style has something to do with this issue though I didn't find any clue about it. Does anyone have any idea? Maybe there's a layer above that doesn't allow to trigger the onHover modifier? Thanks in advance for your help!
1
0
145
1w
Picking image in iOS-first app when running it on macOS 26
An app that is capable of running on iPad can be usually run on Mac if properly designed and that's great. Recently I've tried to launch one of my old apps on macOS 26 in "Designed for iPad" mode and noticed that image picker behaves oddly. Images are barely selectable, you have to click several times and yet it might select image and might not. On iPhone and on iPad any kind of image picking works fine. I've tried all kinds of native pickers (PhotosPicker, PHPickerViewController, UIImagePickerController), but the result is almost the same. So how should I nowadays do image picking in (mostly) iOS app when it is run on macOS? Below is the most canonical and modern code I've tried. The issue is reproduced even with such bare minimum of code with the label not being put to a Form/List or any other factors. import SwiftUI import PhotosUI struct ContentView: View { @State private var selectedItem: PhotosPickerItem? @State private var selectedImage: UIImage? var body: some View { VStack { if let selectedImage { Image(uiImage: selectedImage) .resizable() .scaledToFit() } // Most modern photo library picker, not `PHPickerViewController`, not `UIImagePickerController` based pickerPhotosPicker( selection: $selectedItem, matching: .images ) { Label("Select Photo", systemImage: "photo") } .onChange(of: selectedItem) { newItem inTask { if let data = try? await newItem?.loadTransferable(type: Data.self), let uiImage = UIImage(data: data) { selectedImage = uiImage } } } } } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
3
0
50
1w
NSOutlineView incorrectly draws disclosure indicator when item views are SwiftUI views.
I am using an NSOutlineView via NSViewRepresentable in a SwiftUI application running on macOS. Everything has been working fine. Up until lately, I've been returning a custom NSView for each item using the standard: func outlineView(_ outlineView: NSOutlineView, viewFor tableColumn: NSTableColumn?, item: Any) -> NSView? { // View recycling omitted. return MyItemView(item) } Now I want to explore using a little bit more SwiftUI and returning an NSHostingView from this delegate method. func outlineView(_ outlineView: NSOutlineView, viewFor tableColumn: NSTableColumn?, item: Any) -> NSView? { // View recycling omitted. let rootView = MySwiftUIView(item) let hostingView = NSHostingView(rootView: rootView) return hostingView } For the most part, this appears to be working fine. NSOutlineView is even correctly applying highlight styling, so that's great. But there's one small glitch. The outline view's disclosure triangles do not align with the hosting view's content. The disclosure triangles appear to just be pinned to the top. Perhaps they can't find a baseline constraint or something? Is there any SwiftUI modifier or AppKit/SwiftUI technique I can apply here to get the disclosure button to appear in the right place? Here is what the SwiftUI + NSHostingView version looks like: Note the offset disclosure indicators. (Image spacing is a bit off as well using Label, but fixable. Here is what an NSView with NSTextFields looks like: Disclosure indicators are correctly aligned, as you would expect.
1
0
103
1w
tvOS 26.2 Homescreen Shadow Glitch
Hi @DTS Engineer in tvOS 26.2 Beta is still this annoying Shadow Glitch… I have submitted an Bug-Report, but dont get an Answer… FB20049524 The Animation is not smooth and the Shadow is abruptly „jumping“… I don’t get any Response from the Apple Engineers. But this GUI Glitch makes the otherwise very high-quality tvOS GUI appear very unprofessional. Could you please help me? 🤔
Topic: UI Frameworks SubTopic: General Tags:
0
0
30
1w
SwiftUI Slider onEditingChanged is unreliable on iOS 26
For information I stumbled upon a regression with SwiftUI Slider on iOS 26. Its onEditingChanged closure might be called twice when interaction ends, with a final Boolean incorrect value of true provided to the closure. As a result apps cannot reliably rely on this closure to detect when an interaction with the slider starts or ends. I filed a feedback under FB20283439 (iOS 26.0 regression: Slider onEditingChanged closure is unreliable).
6
5
326
1w
SwiftUI WebView Error
I'm using SwiftUI WebView and this error happens when app becomes inactive, the webview changes to blank, and will be in this state all along even if reopen a new webview. When I switch back to WKWebview, everything works fine. environment Xcode 26.1(17B55) on macOS 15.7.1 Error acquiring assertion: <Error Domain=RBSServiceErrorDomain Code=1 "((target is not running or doesn't have entitlement com.apple.developer.web-browser-engine.rendering AND target is not running or doesn't have entitlement com.apple.developer.web-browser-engine.networking AND target is not running or doesn't have entitlement com.apple.developer.web-browser-engine.webcontent))" UserInfo={NSLocalizedFailureReason=((target is not running or doesn't have entitlement com.apple.developer.web-browser-engine.rendering AND target is not running or doesn't have entitlement com.apple.developer.web-browser-engine.networking AND target is not running or doesn't have entitlement com.apple.developer.web-browser-engine.webcontent))}> this is the code, pretty simple, in load() function i just call page.load(). WebView(vm.page) .onAppear { Task { await vm.load() } }
0
0
71
1w
Navigation bar fade breaks when using .ignoresSafeArea() on inverted ScrollViews in iOS 26
I’m seeing a strange visual bug in iOS 26 when building chat-style UIs that use an inverted ScrollView or List (via .rotationEffect(.radians(.pi)) and .scaleEffect(x: -1, y: 1)) to anchor messages at the bottom. When I add .ignoresSafeArea() to let the chat bleed behind the navigation bar - the new navigation bar fade (that subtle top-to-bottom gradient Apple added in iOS 26) behaves incorrectly. Instead of fading from the top of the screen toward the nav bar, it fades upward from the bottom of the view, effectively covering the entire screen with the gradient. This only happens when the view is inverted. If I remove .ignoresSafeArea(), the fade looks correct — but then my chat no longer extends behind the nav bar. It looks like the fade effect is being applied in the transformed coordinate space of the inverted scroll view rather than in visual screen space. I haven’t found a reliable workaround besides disabling the fade (which isn’t really possible). Has anyone found a proper solution or a modifier that prevents the fade inversion when using flipped ScrollViews? Would love to know if Apple is aware of this or if there’s a hidden API for disabling that fade effect. I have made a report about this in Feedback Assistant: FB20540755
1
0
134
1w
The floating keyboard on iPad OS 26 is not displaying
On iPad OS 26, the custom keyboard works correctly with a full keyboard, but with a floating keyboard, there is only one line and the console displays a constraint error. Unable to simultaneously satisfy constraints. Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. ( "<NSLayoutConstraint:0x600002172c10 V:|-(10)-[TUIKeyboardContentView:0x1039c5410] (active, names: '|':TUIKeyplaneView:0x1039c3e20 )>", "<NSLayoutConstraint:0x600002172c60 V:[TUIKeyboardContentView:0x1039c5410]-(-11)-| (active, names: '|':TUIKeyplaneView:0x1039c3e20 )>", "<NSLayoutConstraint:0x6000021721c0 V:|-(0)-[TUIKeyplaneView:0x1039c3e20] (active, names: UIKeyboardLayoutStar Prev...:0x105160e00, '|':UIKeyboardLayoutStar Prev...:0x105160e00 )>", "<NSLayoutConstraint:0x600002172210 V:[TUIKeyplaneView:0x1039c3e20]-(0)-| (active, names: UIKeyboardLayoutStar Prev...:0x105160e00, '|':UIKeyboardLayoutStar Prev...:0x105160e00 )>", "<NSLayoutConstraint:0x6000021728a0 V:|-(0)-[UIKeyboardLayoutStar Prev...] (active, names: UIKeyboardLayoutStar Prev...:0x105160e00, '|':UIKeyboardImpl:0x109905fa0 )>", "<NSLayoutConstraint:0x6000021728f0 V:[UIKeyboardLayoutStar Prev...]-(0)-| (active, names: UIKeyboardLayoutStar Prev...:0x105160e00, '|':UIKeyboardImpl:0x109905fa0 )>", "<NSLayoutConstraint:0x600002177980 '_UITemporaryLayoutHeight' UIKeyboardImpl:0x109905fa0.height == 0 (active)>", "<NSLayoutConstraint:0x600002172df0 'TUIKeyplane.height' TUIKeyboardContentView:0x1039c5410.height == 217 (active)>" ) Will attempt to recover by breaking constraint <NSLayoutConstraint:0x600002172df0 'TUIKeyplane.height' TUIKeyboardContentView:0x1039c5410.height == 217 (active)> Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger. The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful. iPad OS 26 custom keyboard, full keyboard mode is working normally.
Topic: UI Frameworks SubTopic: UIKit
0
0
54
1w
Keyboard Toolbar Padding iOS26
When I create a SwiftUI toolbar item with placement of .keyboard on iOS 26, the item appears directly on top of and in contact with the keyboard. This does not look good visually nor does it match the behavior seen in Apple's apps, such as Reminders. Adding padding to the contents of the toolbar item only expands the size of the item but does not separate the capsule background of the item from the keyboard. How can I add vertical padding or spacing to separate the toolbar item capsule from the keyboard?
Topic: UI Frameworks SubTopic: SwiftUI
7
5
500
1w
UIViewRepresentable Coordinator @Binding returns stale value when accessed via context.coordinator but fresh value when accessed via self
I'm encountering unexpected behavior with @Binding in a UIViewRepresentable's Coordinator. The same Coordinator instance returns different values depending on how the property is accessed. Environment: iOS 17+ / Xcode 15+ SwiftUI with UIViewRepresentable Issue: When I access @Binding var test inside the Coordinator: ✅ Via self.test in Coordinator methods: Returns the updated value ❌ Via context.coordinator.test in updateUIView: Returns the stale/initial value Both access the same Coordinator instance (verified by memory address), yet return different values. Minimal Reproducible Example: struct ContentView: View { @State private var test: [Int] = [1, 2, 3, 4, 5] var body: some View { VStack { TestRepresentable(test: $test) Text("State: \(test.description)") } } } struct TestRepresentable: UIViewRepresentable { @Binding var test: [Int] func makeUIView(context: Context) -> UIButton { let button = UIButton(type: .system) button.setTitle("Toggle", for: .normal) button.addTarget( context.coordinator, action: #selector(Coordinator.buttonTapped), for: .touchUpInside ) return button } func updateUIView(_ uiView: UIButton, context: Context) { // Log coordinator instance address let coordAddr = String(describing: Unmanaged.passUnretained(context.coordinator).toOpaque()) print("[updateUIView] Coordinator address: \(coordAddr)") // Log values print("[updateUIView] self.test: \(self.test)") print("[updateUIView] context.coordinator.test: \(context.coordinator.test)") // These should be the same but they're not! // self.test shows updated value // context.coordinator.test shows stale value } func makeCoordinator() -> Coordinator { Coordinator(test: $test) } class Coordinator: NSObject { @Binding var test: [Int] var idx: Int = 0 init(test: Binding<[Int]>) { _test = test } @objc func buttonTapped() { idx += 1 if idx < test.count { test[idx] += 5 } // Log coordinator instance address let selfAddr = String(describing: Unmanaged.passUnretained(self).toOpaque()) print("[buttonTapped] Coordinator address: \(selfAddr)") // Log value - this shows the UPDATED value print("[buttonTapped] self.test: \(test)") } } } Actual Output: [Initial] [updateUIView] Coordinator address: 0x600001234567 [updateUIView] self.test: [1, 2, 3, 4, 5] [updateUIView] context.coordinator.test: [1, 2, 3, 4, 5] [After first tap] [buttonTapped] Coordinator address: 0x600001234567 [buttonTapped] self.test: [1, 7, 3, 4, 5] ✅ Updated! [updateUIView] Coordinator address: 0x600001234567 ← Same instance [updateUIView] self.test: [1, 7, 3, 4, 5] ✅ Updated! [updateUIView] context.coordinator.test: [1, 2, 3, 4, 5] ❌ Stale! [After second tap] [buttonTapped] Coordinator address: 0x600001234567 [buttonTapped] self.test: [1, 7, 8, 4, 5] ✅ Updated! [updateUIView] Coordinator address: 0x600001234567 ← Same instance [updateUIView] self.test: [1, 7, 8, 4, 5] ✅ Updated! [updateUIView] context.coordinator.test: [1, 2, 3, 4, 5] ❌ Still stale! Questions: Why does context.coordinator.test return a stale value when it's the same Coordinator instance? Is this intended behavior or a bug? What's the correct pattern to access Coordinator's @Binding properties in updateUIView? Workaround Found: Using self.test instead of context.coordinator.test in updateUIView works, but I'd like to understand why accessing the same property through context yields different results. Related: I've seen suggestions to update coordinator.parent = self in updateUIView, but this doesn't explain why the same object's property returns different values. Binding documentation states it's "a pair of get and set closures," but there's no explanation of how Context affects closure behavior. Any insights would be greatly appreciated! P.S - https://stackoverflow.com/questions/69552418/why-does-a-binding-in-uiviewrepresentables-coordinator-have-a-constant-read-valu This is the link that I found out online with same problem that I have but not answered well.
0
0
25
1w
UICollectionView Move Item Method Not Called in iOS 18
Summary In iOS 18, the UICollectionViewDelegate method collectionView(_:targetIndexPathForMoveOfItemFromOriginalIndexPath:atCurrentIndexPath:toProposedIndexPath:) is not being called when moving items in a UICollectionView. This method works as expected in iOS 17.5 and earlier versions. Steps to Reproduce Create a UICollectionView with drag and drop enabled. Implement the UICollectionViewDelegate method: func collectionView(_ collectionView: UICollectionView, targetIndexPathForMoveOfItemFromOriginalIndexPath originalIndexPath: IndexPath, atCurrentIndexPath currentIndexPath: IndexPath, toProposedIndexPath proposedIndexPath: IndexPath) -> IndexPath { print("🐸 Move") return proposedIndexPath } Run the app on iOS 18. Attempt to drag and drop items within the collection view. Expected Behavior The method should be called during the drag and drop operation, and "🐸 Move" should be printed to the console. Actual Behavior The method is not called, and nothing is printed to the console. The drag and drop operation still occurs, but without invoking this delegate method. Configuration iOS Version: 18 Xcode Version: Xcode 16.0.0
Topic: UI Frameworks SubTopic: UIKit Tags:
4
3
629
1w
Slow rendering List backed by SwiftData @Query
Hello, I've a question about performance when trying to render lots of items coming from SwiftData via a @Query on a SwiftUI List. Here's my setup: // Item.swift: @Model final class Item: Identifiable { var timestamp: Date var isOptionA: Bool init() { self.timestamp = Date() self.isOptionA = Bool.random() } } // Menu.swift enum Menu: String, CaseIterable, Hashable, Identifiable { var id: String { rawValue } case optionA case optionB case all var predicate: Predicate<Item> { switch self { case .optionA: return #Predicate { $0.isOptionA } case .optionB: return #Predicate { !$0.isOptionA } case .all: return #Predicate { _ in true } } } } // SlowData.swift @main struct SlowDataApp: App { var sharedModelContainer: ModelContainer = { let schema = Schema([Item.self]) let modelConfiguration = ModelConfiguration(schema: schema, isStoredInMemoryOnly: false) return try! ModelContainer(for: schema, configurations: [modelConfiguration]) }() var body: some Scene { WindowGroup { ContentView() } .modelContainer(sharedModelContainer) } } // ContentView.swift struct ContentView: View { @Environment(\.modelContext) private var modelContext @State var selection: Menu? = .optionA var body: some View { NavigationSplitView { List(Menu.allCases, selection: $selection) { menu in Text(menu.rawValue).tag(menu) } } detail: { DemoListView(selectedMenu: $selection) }.onAppear { // Do this just once // (0..<15_000).forEach { index in // let item = Item() // modelContext.insert(item) // } } } } // DemoListView.swift struct DemoListView: View { @Binding var selectedMenu: Menu? @Query private var items: [Item] init(selectedMenu: Binding<Menu?>) { self._selectedMenu = selectedMenu self._items = Query(filter: selectedMenu.wrappedValue?.predicate, sort: \.timestamp) } var body: some View { // Option 1: touching `items` = slow! List(items) { item in Text(item.timestamp.description) } // Option 2: Not touching `items` = fast! // List { // Text("Not accessing `items` here") // } .navigationTitle(selectedMenu?.rawValue ?? "N/A") } } When I use Option 1 on DemoListView, there's a noticeable delay on the navigation. If I use Option 2, there's none. This happens both on Debug builds and Release builds, just FYI because on Xcode 16 Debug builds seem to be slower than expected: https://indieweb.social/@curtclifton/113273571392595819 I've profiled it and the SwiftData fetches seem blazing fast, the Hang occurs when accessing the items property from the List. Is there anything I'm overlooking or it's just as fast as it can be right now?
4
4
1.2k
1w
Drag and Drop stopped working after upgrading from macOS 15 to 26
When I drag and drop a file with flag "shouldAttemptToOpenInPlace: true", I was able to access the original file name in macOS 15. After upgrading to macOS 26, I can't access the original file name anymore. Instead, I got some useless file name such as ".com.apple.Foundation.NSItemProvider.gKZ91u.tmp". The app no longer works with these tmp filenames because it needs the orignal file name to do the file transfer. (Btw, this is a WinSCP like app on Mac platform) Could you please check and fix this issue? Thank you. FileRepresentation(contentType: .item, shouldAttemptToOpenInPlace: true)
1
0
188
1w
Tinted widgets have an inset background in the widget gallery only
When the home screen is in tinted mode in iOS 18, the widget gallery seems to display widgets with the background inset from the edge of the widget (i.e. negative padding). You can see this behavior in the Apple News widget too, where the full-bleed content outside of the inset is very light. This only happens in the sample gallery, not when the widgets are placed on the home screen. For my widgets, this outer edge contains important content and the clipping behavior makes the widgets look poorly designed when viewed in the gallery. Is there any way to turn this behavior off and just show the widget normally in the gallery with no weird inset — the way it will actually display when added to the home screen? If it matters, my widgets are currently configured with: .contentMarginsDisabled() .containerBackground(for: .widget) { // ... (background color) */ }
3
0
549
1w
Change to safe area logic on iOS 26
I have a few view controllers in a large UIKit application that previously started showing content right below the bottom of the top navigation toolbar. When testing the same code on iOS 26, these same views have their content extend under the navigation bar and toolbar. I was able to fix it with: if #available(iOS 26, *, *) { self.edgesForExtendedLayout = [.bottom] } when running on iOS 26. I also fixed one or two places where the main view was anchored to self.view.topAnchor instead of self.view.safeAreaLayoutGuide.topAnchor. Although this seems to work, I wonder if this was an intended change in iOS 26 or just a temporary bug in the beta that will be resolved. Were changes made to the safe area and edgesForExtendedLayout logic in iOS 26? If so, is there a place I can see what the specific changes were, so I know my code is handling it properly? Thanks!
Topic: UI Frameworks SubTopic: UIKit
7
6
1.1k
1w
Dual .fileImporter modifier only one is called
On macOS I'm seeing that only one .fileImporter modifier is called when two are defined. Anybody seeing the same issue? The scenario I have is two different file sources share the same file extension but they need to be loaded by two slightly different processes. Select the first option. Nothing happens. Select the second option, it works. Seeing this also in another project. Because the isPresented value is a binding, it isn't straightforward to logically OR the boolean @States and conditionally extract within the import closure. @main struct Dual_File_Importer_ExpApp: App { @State private var showFirstDialog = false @State private var showSecondDialog = false var body: some Scene { DocumentGroup(newDocument: Dual_File_Importer_ExpDocument()) { file in ContentView(document: file.$document) .fileImporter(isPresented: $showFirstDialog, allowedContentTypes: [.commaSeparatedText]) { result in print("first") } .fileImporter(isPresented: $showSecondDialog, allowedContentTypes: [.commaSeparatedText]) { result in print("second") } } .commands { CommandGroup(after: .importExport) { Button("Import First") { showFirstDialog.toggle() } Button("Import Second") { showSecondDialog.toggle() } } } } }```
Topic: UI Frameworks SubTopic: SwiftUI
2
0
66
1w
List Section with Swipe Action - glitches
Overview I have an iOS project where I have a list with sections. Each cell in the section can be swiped to have some action What needs to be done When swipe button is pressed the cell needs to move from one section to the other without a UI glitch. Problem When I press the swipe action button, there is a UI glitch and some warnings are thrown. UICollectionView internal inconsistency: unexpected removal of the current swipe occurrence's mask view. Please file a bug against UICollectionView. Reusable view: <SwiftUI.ListCollectionViewCell: 0x10700c200; baseClass = UICollectionViewListCell; frame = (16 40.3333; 370 52); hidden = YES; layer = <CALayer: 0x600000c12fa0>>; Collection view: <SwiftUI.UpdateCoalescingCollectionView: 0x106820800; baseClass = UICollectionView; frame = (0 0; 402 874); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x600000c13330>; backgroundColor = <UIDynamicSystemColor: 0x60000173a9c0; name = systemGroupedBackgroundColor>; layer = <CALayer: 0x600000c3a070>; contentOffset: {0, -62}; contentSize: {402, 229}; adjustedContentInset: {62, 0, 34, 0}; layout: <UICollectionViewCompositionalLayout: 0x10590edb0>; dataSource: <_TtGC7SwiftUI31UICollectionViewListCoordinatorGVS_28CollectionViewListDataSourceOs5Never_GOS_19SelectionManagerBoxS2___: 0x106822a00>>; Swipe occurrence: <UISwipeOccurrence: 0x103c161f0; indexPath: <NSIndexPath: 0xab1f048608f3828b> {length = 2, path = 0 - 0}, state: .triggered, direction: left, offset: 0> Test environment: Xcode 26.0.1 (17A400) iOS 26 Simulator (iPhone 17 Pro) Feedback filed: FB20890361 Code I have pasted below the minimum reproducible code ContentView import SwiftUI struct ContentView: View { @State private var dataStore = DataStore() var body: some View { List { ToDoSection(status: .notStarted, toDos: notStartedToDos) ToDoSection(status: .inProgress, toDos: inProgressToDos) ToDoSection(status: .completed, toDos: completedTodos) } } var notStartedToDos: [Binding<ToDoItem>] { $dataStore.todos.filter { $0.wrappedValue.status == .notStarted } } var inProgressToDos: [Binding<ToDoItem>] { $dataStore.todos.filter { $0.wrappedValue.status == .inProgress } } var completedTodos: [Binding<ToDoItem>] { $dataStore.todos.filter { $0.wrappedValue.status == .completed } } } ToDoSection import SwiftUI struct ToDoSection: View { let status: ToDoItem.Status let toDos: [Binding<ToDoItem>] var body: some View { if !toDos.isEmpty { Section(status.title) { ForEach(toDos) { toDo in Text(toDo.wrappedValue.title) .swipeActions(edge: .trailing) { if status == .notStarted { Button("Start") { toDo.wrappedValue.status = .inProgress } } if status != .completed { Button("Complete") { toDo.wrappedValue.status = .completed } Button("Move back") { toDo.wrappedValue.status = .notStarted } } } } } } } } ToDoItem import Foundation struct ToDoItem: Identifiable { let id: UUID let title: String var status: Status } extension ToDoItem { enum Status: Equatable { case notStarted case inProgress case completed var title: String { switch self { case .notStarted: "Not Started" case .inProgress: "In Progress" case .completed: "Completed" } } } } DataStore import Foundation @Observable class DataStore { var todos: [ToDoItem] init() { todos = [ ToDoItem(id: UUID(), title: "aaa", status: .notStarted), ToDoItem(id: UUID(), title: "bbb", status: .notStarted), ToDoItem(id: UUID(), title: "ccc", status: .notStarted) ] } }
Topic: UI Frameworks SubTopic: SwiftUI
4
1
200
1w
Tab bar alignment issue from iOS 26
I have a tab bar with 4 tabs. Since iOS 26, I’m facing an issue with the tab alignment — the text automatically shrinks, and the tab icon shifts upward for some tabs. I am using UITab property for creating Tabs from os Version above 18 and UITabBar for os version below 18.
1
1
98
1w
Keyframe animation crashes with +[_SwiftUILayerDelegate _screen]: unrecognized selector sent to class on iOS 26
We have an UIViewController called InfoPlayerViewController. Its main subview is from a child view controller backed by SwiftUI via UIHostingController. The InfoPlayerViewController conforms to UIViewControllerTransitioningDelegate. The animation controller for dismissing is DismissPlayerAnimationController. It runs UIKit keyframe animations via UIViewPropertyAnimator. When the keyframe animation is executed there’s an occasional crash for end users in production. It only happens on iOS 26. FB Radar: FB20871547 An example crash is below. Exception Type: EXC_CRASH (SIGABRT) Exception Codes: 0x0000000000000000, 0x0000000000000000 Exception Reason: +[_SwiftUILayerDelegate _screen]: unrecognized selector sent to class 0x20c95da08 Termination Reason: SIGNAL 6 Abort trap: 6 Triggered by Thread: 0 Last Exception Backtrace: 0 CoreFoundation 0x1a23828c8 __exceptionPreprocess + 164 (NSException.m:249) 1 libobjc.A.dylib 0x19f2f97c4 objc_exception_throw + 88 (objc-exception.mm:356) 2 CoreFoundation 0x1a241e6cc +[NSObject(NSObject) doesNotRecognizeSelector:] + 364 (NSObject.m:158) 3 CoreFoundation 0x1a22ff4f8 ___forwarding___ + 1472 (NSForwarding.m:3616) 4 CoreFoundation 0x1a23073a0 _CF_forwarding_prep_0 + 96 (:-1) 5 UIKitCore 0x1a948e880 __35-[UIViewKeyframeAnimationState pop]_block_invoke + 300 (UIView.m:2973) 6 CoreFoundation 0x1a22cb170 __NSDICTIONARY_IS_CALLING_OUT_TO_A_BLOCK__ + 24 (NSDictionaryHelpers.m:10) 7 CoreFoundation 0x1a245d7cc -[__NSDictionaryM enumerateKeysAndObjectsWithOptions:usingBlock:] + 288 (NSDictionaryM.m:271) 8 UIKitCore 0x1a948e6bc -[UIViewKeyframeAnimationState pop] + 376 (UIView.m:2955) 9 UIKitCore 0x1a7bc40e8 +[UIViewAnimationState popAnimationState] + 60 (UIView.m:1250) 10 UIKitCore 0x1a94acc44 +[UIView(UIViewAnimationWithBlocks) _setupAnimationWithDuration:delay:view:options:factory:animations:start:animationStateGenerator:completion:] + 684 (UIView.m:17669) 11 UIKitCore 0x1a94ae334 +[UIView(UIViewKeyframeAnimations) animateKeyframesWithDuration:delay:options:animations:completion:] + 224 (UIView.m:17945) 12 MyApp 0x102c78dec static UIView.animateNestedKeyframe(withRelativeStartTime:relativeDuration:animations:) + 208 (UIView+AnimateNestedKeyframe.swift:10) 13 MyApp 0x102aef3c0 closure #1 in DismissPlayerAnimationController.slideDownBelowTabBarTransitionAnimator(using:) + 156 (DismissPlayerAnimationController.swift:229) 14 MyApp 0x102a2d3d4 <deduplicated_symbol> + 28 15 UIKitCore 0x1a7d5ae5c -[UIViewPropertyAnimator _runAnimations] + 172 (UIViewPropertyAnimator.m:2123) 16 UIKitCore 0x1a83e1594 __49-[UIViewPropertyAnimator startAnimationAsPaused:]_block_invoke_3 + 92 (UIViewPropertyAnimator.m:3557) 17 UIKitCore 0x1a83e1464 __49-[UIViewPropertyAnimator startAnimationAsPaused:]_block_invoke + 96 (UIViewPropertyAnimator.m:3547) 18 UIKitCore 0x1a83e1518 __49-[UIViewPropertyAnimator startAnimationAsPaused:]_block_invoke_2 + 144 (UIViewPropertyAnimator.m:3553) 19 UIKitCore 0x1a83e0e64 -[UIViewPropertyAnimator _setupAnimationTracking:] + 100 (UIViewPropertyAnimator.m:3510) 20 UIKitCore 0x1a83e1264 -[UIViewPropertyAnimator startAnimationAsPaused:] + 728 (UIViewPropertyAnimator.m:3610) 21 UIKitCore 0x1a83de42c -[UIViewPropertyAnimator pauseAnimation] + 68 (UIViewPropertyAnimator.m:2753) 22 UIKitCore 0x1a87d5328 -[UIPercentDrivenInteractiveTransition _startInterruptibleTransition:] + 244 (UIViewControllerTransitioning.m:982) 23 UIKitCore 0x1a87d5514 -[UIPercentDrivenInteractiveTransition startInteractiveTransition:] + 184 (UIViewControllerTransitioning.m:1012) 24 UIKitCore 0x1a7c7931c ___UIViewControllerTransitioningRunCustomTransitionWithRequest_block_invoke_3 + 152 (UIViewControllerTransitioning.m:1579) 25 UIKitCore 0x1a892aefc +[UIKeyboardSceneDelegate _pinInputViewsForKeyboardSceneDelegate:onBehalfOfResponder:duringBlock:] + 96 (UIKeyboardSceneDelegate.m:3518) 26 UIKitCore 0x1a7c79238 ___UIViewControllerTransitioningRunCustomTransitionWithRequest_block_invoke_2 + 236 (UIViewControllerTransitioning.m:1571) 27 UIKitCore 0x1a94ab4b8 +[UIView(Animation) _setAlongsideAnimations:toRunByEndOfBlock:animated:] + 188 (UIView.m:17089) 28 UIKitCore 0x1a7c79070 _UIViewControllerTransitioningRunCustomTransitionWithRequest + 556 (UIViewControllerTransitioning.m:1560) 29 UIKitCore 0x1a86cb7cc __77-[UIPresentationController runTransitionForCurrentStateAnimated:handoffData:]_block_invoke_3 + 1784 (UIPresentationController.m:1504) 30 UIKitCore 0x1a7c43888 -[_UIAfterCACommitBlock run] + 72 (_UIAfterCACommitQueue.m:137) 31 UIKitCore 0x1a7c437c0 -[_UIAfterCACommitQueue flush] + 168 (_UIAfterCACommitQueue.m:228) 32 UIKitCore 0x1a7c436d0 _runAfterCACommitDeferredBlocks + 260 (UIApplication.m:3297) 33 UIKitCore 0x1a7c43c34 _cleanUpAfterCAFlushAndRunDeferredBlocks + 80 (UIApplication.m:3275) 34 UIKitCore 0x1a7c1f104 _UIApplicationFlushCATransaction + 72 (UIApplication.m:3338) 35 UIKitCore 0x1a7c1f024 __setupUpdateSequence_block_invoke_2 + 352 (_UIUpdateScheduler.m:1634) 36 UIKitCore 0x1a7c2cee8 _UIUpdateSequenceRunNext + 128 (_UIUpdateSequence.mm:189) 37 UIKitCore 0x1a7c2c378 schedulerStepScheduledMainSectionContinue + 60 (_UIUpdateScheduler.m:1185) 38 UpdateCycle 0x28c58f5f8 UC::DriverCore::continueProcessing() + 84 (UCDriver.cc:288) 39 CoreFoundation 0x1a2323230 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 28 (CFRunLoop.c:2021) 40 CoreFoundation 0x1a23231a4 __CFRunLoopDoSource0 + 172 (CFRunLoop.c:2065) 41 CoreFoundation 0x1a2300c6c __CFRunLoopDoSources0 + 232 (CFRunLoop.c:2102) 42 CoreFoundation 0x1a22d68b0 __CFRunLoopRun + 820 (CFRunLoop.c:2983) 43 CoreFoundation 0x1a22d5c44 _CFRunLoopRunSpecificWithOptions + 532 (CFRunLoop.c:3462) 44 GraphicsServices 0x2416a2498 GSEventRunModal + 120 (GSEvent.c:2049) 45 UIKitCore 0x1a7c50ddc -[UIApplication _run] + 792 (UIApplication.m:3899) 46 UIKitCore 0x1a7bf5b0c UIApplicationMain + 336 (UIApplication.m:5574) // ...
2
1
259
1w
UICollectionViewDelegate method not invoked
I’m running the interactive reordering sample from this repo and hitting an odd behavior on newer simulators: the delegate method that lets you steer the drop: func collectionView(_:targetIndexPathForMoveOfItemFromOriginalIndexPath:atCurrentIndexPath:toProposedIndexPath:) works fine on iOS 16, but on iOS 18 and iOS 26 simulators it never fires, so the item always lands at the proposed index path and I can’t constrain moves or adjust the compositional view layout to accommodate the cell of different size. Is this a new behavior in modern iOS? If so, what’s the recommended way to control the final index path for the UICollectionViewDropDelegate now?
Topic: UI Frameworks SubTopic: UIKit Tags:
0
1
31
1w