Explore the various UI frameworks available for building app interfaces. Discuss the use cases for different frameworks, share best practices, and get help with specific framework-related questions.

All subtopics
Posts under UI Frameworks topic

Post

Replies

Boosts

Views

Created

DocumentGroupLaunchScene corrupts the toolbar for DocumentGroup content views.
The sample code provided in "Building a document-based app with SwiftUI" (https://developer.apple.com/documentation/swiftui/building-a-document-based-app-with-swiftui) does not work as expected. The DocumentGroup/StoryView toolbar does not appear for documents opened in the App. By removing the DocumentGroupLaunchScene block from the App the toolbar does appear and works as expected - but of course the App's DocumentGroupLaunchScene customizations are lost. I've tested this on 18.0 devices, as well as production 18.0 and 18.1 beta 6 simulators. If I modify the StoryView by wrapping the content in a NavigationStack I can make some progress - but the results are unstable and hard to pin down - with this change the first time a document is opened in the WritingApp the toolbar appears as expected. When opening a document subsequently the toolbar is corrupted. Please is this a bug or is there a good example of incorporate both DocumentGroupLaunchScene customizations at the App level and retina the toolbar in documents presented via DocumentGroup?
Topic: UI Frameworks SubTopic: SwiftUI
12
4
710
Oct ’24
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
1k
Oct ’24
AreaMark Always alignsMarkStylesWithPlotArea for linear gradients
I'm trying to make a Swift Chart where 24 AreaMarks an hour apart on X axis over a day display a vertical gradient. The gradient is vertical and is essentially [Color.opacity(0.1),Colour,Color.opacity(0.1] The idea here is where the upper and lower points of each AreaMark are the same or close to each other in the Y axis, the chart essentially displays a line, where they are far apart you get a nice fading vertical gradient. However, it seems that the .alignsMarkStylesWithPlotArea modifier is always set for AreaMarks even if manually applying it false. Investigating further, I've learnt that with AreaMarks in a series, Swift Charts seems to only listen to the first foreground style set in. I've created some sample code to demonstrate this. struct DemoChartView: View { var body: some View { Chart { AreaMark(x: .value("Time", Date().addingTimeInterval(0)), yStart: .value("1", 40), yEnd: .value("2", 60)) .foregroundStyle(LinearGradient(colors: [.pink, .teal], startPoint: .top, endPoint: .bottom)) .alignsMarkStylesWithPlotArea(false) AreaMark(x: .value("Time", Date().addingTimeInterval(3600)), yStart: .value("1", 44), yEnd: .value("2", 58)) .foregroundStyle(LinearGradient(colors: [.orange, .yellow], startPoint: .top, endPoint: .bottom)) .alignsMarkStylesWithPlotArea(false) AreaMark(x: .value("Time", Date().addingTimeInterval(03600*2)), yStart: .value("1", 50), yEnd: .value("2", 90)) .foregroundStyle(LinearGradient(colors: [.green, .blue], startPoint: .top, endPoint: .bottom)) .alignsMarkStylesWithPlotArea(false) } } } Which produces this: So here, all the different .foregroundStyle LinearGradients are being ignored AND the .alignsMarkStylesWithPlotArea(false) is also ignored - the amount of pink on the first mark is different to the second and third 🤷‍♂️ Has anyone encountered this. Are AreaMarks the correct choice or are they just not setup to create this type of data display. Thanks
3
0
858
Oct ’24
AppIntentTimelineProvider "func timeline(for" is called twice after a widget button triggers an AppIntent Perform
I'm adding widget interactivity to my home screen widgets via buttons and AppIntents, but running into some interesting behavior the way the timeline is reloaded after. I'm following this guide from Apple https://developer.apple.com/documentation/widgetkit/adding-interactivity-to-widgets-and-live-activities And the widget is guaranteed to be reloaded when a button pressed with an intent, But whenever the AppIntent is done with the perform action, the widget timeline is always reloaded twice. It's also interesting to note that both reloads happen after the perform method. If you add a 10 second sleep in the perform, nothing happens for 10 seconds, then both reloads happen. This issue with this is 2-fold. calculating and rendering the entire widget timeline can be Networking and DB intensive operations, so I would ideally like to avoid doing all the work twice and save the users battery and processing. The even worse issue, sometimes data on the server changes in between the split second duplicate widget timeline reloads, causing the widget to flash one state, then update to another a second later which is not a good user experience. I have a sample project which shows the issue and is very easy to reproduce. The widget simply keeps track of the number of reloads. To reproduce: Add the widget to the homescreen Press the refresh button, and observe the timeline refresh count always goes up by 2. I've filed a Feedback and attached the sample project and screen recording for anyone to reproduce. FB15595835
3
0
808
Oct ’24
Is this log noise? "CoreSVG: Error: NULL ref passed to getObjectCoreSVG: Error: NULL ref passed to getObject"
Before I waste time creating an Apple Developer Support ticket, I’m hoping an Apple DTS engineer can confirm if this is just log noise. Here’s the code: import SwiftUI struct ContentView: View { @State private var editMode: EditMode = .inactive @State private var items = ["Item 1", "Item 2", "Item 3"] var body: some View { NavigationStack { List { ForEach(items, id: \.self) { item in Text(item) } .onDelete { indexSet in items.remove(atOffsets: indexSet) } } .environment(\.editMode, $editMode) .toolbar { ToolbarItem(placement: .topBarTrailing) { EditButton() .environment(\.editMode, $editMode) } } } } } #Preview { ContentView() } When you run this code and tap Edit, you’ll initially get: CoreSVG has logged an error. Set environment variabe [sic] "CORESVG_VERBOSE" to learn more. After setting CORESVG_VERBOSE = YES, you’ll see: CoreSVG: Error: NULL ref passed to getObjectCoreSVG: Error: NULL ref passed to getObject This error only appears the first time Edit is tapped after a build and run. It won't happen again, even after force-quitting and reopening the app. The issue also only happens on iOS 18.0 and 18.1—I can’t reproduce it on iOS 17.5. Fortunately, it doesn’t seem to cause any negative side effects. Is this just log noise?
Topic: UI Frameworks SubTopic: SwiftUI
3
5
1.7k
Oct ’24
New crashes with NSOutlineView in MacOS Sequoia
Hi, I have noticed a major uptick in crash reports, ever since I updated my app for macOS Sequoia. All of them have to do with NSOutlineView, and they all have a similar internal API in the crash log, which shows that the issue is something to do with the framework. They all have references to NSConcreteMapTable and _TtCs12_SwiftObject isEqual. The issue isn't reproducible, but it's reported by many different users, all on macOS15+, and it was never an issue with macOS14 or below, so I'm not sure what to do about it. Here's a couple of examples of the new crash reports: Date/Time: 2024-10-29T06:55:19.999Z Launch Time: 2024-10-29T06:50:08Z OS Version: Mac OS X 15.0.1 (24A348) Report Version: 104 Exception Type: SIGTRAP Exception Codes: TRAP_BRKPT at 0x1a98c9c90 Crashed Thread: 0 Thread 0 Crashed: 0 libswiftCore.dylib 0x00000001a98c9c90 -[_TtCs12_SwiftObject isEqual:] + 240 1 Foundation 0x0000000199ad4e0c probeGC + 408 2 Foundation 0x0000000199b01e6c -[NSConcreteMapTable removeObjectForKey:] + 76 3 AppKit 0x000000019c5966a8 _NSOVFreeRowEntry + 44 4 AppKit 0x000000019c5965c4 _NSOVRecursiveFreeChildrenAndItem + 100 5 AppKit 0x000000019c59649c _NSOVFastRemoveChildRowEntries + 260 6 AppKit 0x000000019c595d40 -[NSOutlineView reloadItem:reloadChildren:] + 1016 7 MyApp 0x0000000104b454fc CJ_CRM.MacCJSidebarViewController.compareContactsDictionariesForPublicGroups() -> () (MacCJSidebarViewController.swift:1611) 8 MyApp 0x0000000104b44518 $s20MyApp26MacCJSidebarViewControllerC27contactsChangedNotificationyySo14NSNotificationCFySo7NSTimerCYbcfU_ (MacCJSidebarViewController.swift:461) 9 MyApp 0x0000000104ba5310 $sSo7NSTimerCIeghg_ABIeyBhy_TR (<compiler-generated>:0) 10 Foundation 0x0000000199b64cfc __NSFireTimer + 100 11 CoreFoundation 0x0000000198988184 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 28 12 CoreFoundation 0x0000000198987e28 __CFRunLoopDoTimer + 1008 13 CoreFoundation 0x0000000198987938 __CFRunLoopDoTimers + 352 14 CoreFoundation 0x000000019896d0f0 __CFRunLoopRun + 1852 15 CoreFoundation 0x000000019896c334 CFRunLoopRunSpecific + 568 16 HIToolbox 0x00000001a3da50cc RunCurrentEventLoopInMode + 288 17 HIToolbox 0x00000001a3daaebc ReceiveNextEventCommon + 632 18 HIToolbox 0x00000001a3dab020 _BlockUntilNextEventMatchingListInModeWithFilter + 72 19 AppKit 0x000000019c4b0a70 _DPSNextEvent + 656 20 AppKit 0x000000019cdd67b8 -[NSApplication(NSEventRouting) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 684 21 AppKit 0x000000019c4a3b7c -[NSApplication run] + 476 22 AppKit 0x000000019c47a44c NSApplicationMain + 884 23 MyApp 0x0000000104a1e26c main (main.m:24) 24 ??? 0x0000000198504274 0x0 + 0 Another one with a different trigger but same internal API: Date/Time: 2024-10-29T16:49:12.999Z Launch Time: 2024-10-29T15:51:27Z OS Version: Mac OS X 15.1 (24B83) Report Version: 104 Exception Type: SIGSEGV Exception Codes: SEGV_MAPERR at 0x4cde11282080 Crashed Thread: 0 Thread 0 Crashed: 0 libswiftCore.dylib 0x00000001a04efa1c isSubclass(swift::TargetMetadata<swift::InProcess> const*, swift::TargetMetadata<swift::InProcess> const*) + 28 1 libswiftCore.dylib 0x00000001a04ef9f8 _swift_class_isSubclass + 12 2 libswiftCore.dylib 0x00000001a04ffa9c -[_TtCs12_SwiftObject isEqual:] + 252 3 Foundation 0x00000001906b4cec probeGC + 408 4 Foundation 0x00000001906b4adc -[NSConcreteMapTable objectForKey:] + 64 5 AppKit 0x00000001930f8eec -[NSOutlineView _rowEntryForItem:requiredRowEntryLoadMask:] + 48 6 AppKit 0x00000001930f8e80 -[NSOutlineView parentForItem:] + 24 7 MyApp 0x0000000100e2faec MyApp.MacCJSidebarViewController.outlineView(_: __C.NSOutlineView, selectionIndexesForProposedSelection: Foundation.IndexSet) -> Foundation.IndexSet (MacCJSidebarViewController.swift:759) 8 MyApp 0x0000000100e30dbc @objc MyApp.MacCJSidebarViewController.outlineView(_: __C.NSOutlineView, selectionIndexesForProposedSelection: Foundation.IndexSet) -> Foundation.IndexSet (<compiler-generated>:0) 9 AppKit 0x000000019324c4e4 -[NSTableView _userSelectableRowIndexesForProposedSelection:userCanAlreadyChangeSelection:] + 288 10 AppKit 0x00000001933176c4 -[NSTableView _userSelectRowIndexes:withNewSelectedRow:] + 140 11 AppKit 0x00000001933175a0 -[NSTableView _userSelectSingleRow:] + 76 12 AppKit 0x0000000193315c8c -[NSTableView mouseDown:] + 2536 13 AppKit 0x0000000193315120 -[NSOutlineView mouseDown:] + 72 14 MyApp 0x0000000100dabb38 -[CustomNSOutlineView mouseDown:] (CustomNSOutlineView.m:180) 15 AppKit 0x000000019320d98c forwardMethod + 248 16 AppKit 0x000000019320d98c forwardMethod + 248 17 AppKit 0x0000000193213518 -[NSWindow(NSEventRouting) _handleMouseDownEvent:isDelayedEvent:] + 3668 18 AppKit 0x000000019319f00c -[NSWindow(NSEventRouting) _reallySendEvent:isDelayedEvent:] + 380 19 AppKit 0x000000019319ecbc -[NSWindow(NSEventRouting) sendEvent:] + 280 20 AppKit 0x00000001939b6bf0 -[NSApplication(NSEventRouting) sendEvent:] + 1652 21 AppKit 0x00000001935c489c -[NSApplication _handleEvent:] + 56 22 AppKit 0x000000019306ab08 -[NSApplication run] + 516 23 AppKit 0x0000000193041364 NSApplicationMain + 884 24 MyApp 0x0000000100d0626c main (main.m:24) 25 ??? 0x000000018f0e4274 0x0 + 0 I just created a Feedback FB15625970. Please let me know if this is a known issue, and/or if there's any ideas out there on how I can do to avoid this. It's causing a lot of instability in my app, that wasn't there before macOS15, so something changed in the internal APIs, and hopefully there's a way to work around it.
Topic: UI Frameworks SubTopic: AppKit Tags:
1
1
714
Oct ’24
SwiftUI 'List' performance issue on macOS
Hi, When using SwiftUI ‘List’ with a large number of elements (4000+), I noticed a significant performance issue if extracting the views inside the ‘ForEach’ block into their own subview class. It affects scrolling performance, and using the scroll handle in the scrollbar causes stutters and beachballs. This seems to happen on macOS only ... the same project works fine on iOS. Here's an example of what I mean: List (selection: $multiSelectedContacts) { ForEach(items) { item in // 1. this subview is the problem ... replace it with the contents of the subview, and it works fine PlainContentItemView(item: item) // 2. Uncomment this part for it to work fine (and comment out PlainContentItemView above) /*HStack { if let timestamp = item.timestamp, let itemNumber = item.itemNumber { Text("\(itemNumber) - \(timestamp, formatter: itemFormatter)") } }*/ } } struct PlainContentItemView: View { let item: Item var body: some View { HStack { if let timestamp = item.timestamp, let itemNumber = item.itemNumber { Text("\(itemNumber) - \(timestamp, formatter: itemFormatter)") } } } } Item is a NSManagedObject subclass, and conforms to Identifiable by using the objectID string value. With this, scrolling up and down using the scrolling handle, causes stuttering scrolling and can beachball on my machine (MacBook Pro M1). If I comment out the ‘PlainContentItemView’ and just use the HStack directly (which is what was extracted to ‘PlainContentItemView’), the performance noticeably improves, and I can scroll up and down smoothly. Is this just a bug with SwiftUI, and/or can I do something to improve this?
3
0
731
Oct ’24
Sheet presentationDetents breaks after rapid open/dismiss cycles
Basic Information Please provide a descriptive title for your feedback: Sheet presentationDetents breaks after rapid open/dismiss cycles Which platform is most relevant for your report? iOS Description Steps to Reproduce: Create a sheet with presentationDetents([.medium]) Rapidly perform these actions multiple times (usually 3-4 times): a. Open the sheet b. Immediately scroll down to dismiss Open the sheet again Observe that the sheet now appears at .large size, ignoring the .medium detent Expected Result: Sheet should consistently maintain .medium size regardless of how quickly it is opened and dismissed. Actual Result: After rapid open/dismiss cycles, the sheet ignores .medium detent and appears at .large size. Reproduction Rate: Occurs consistently after 3-4 rapid open/dismiss cycles More likely to occur with faster open/dismiss actions Configuration: iOS 18 Xcode 16.0 (16A242d) SwiftUI Device: iPhone 14
11
8
1.3k
Nov ’24
SwiftUI View cannot conform custom Equatable protocol in Swift 6.
In Swift 6, stricter concurrency rules can lead to challenges when making SwiftUI views conform to Equatable. Specifically, the == operator required for Equatable must be nonisolated, which means it cannot access @MainActor-isolated properties. This creates an error when trying to compare views with such properties: Error Example: struct MyView: View, Equatable { let title: String let count: Int static func ==(lhs: MyView, rhs: MyView) -> Bool { // Accessing `title` here would trigger an error due to actor isolation. return lhs.count == rhs.count } var body: some View { Text(title) } } Error Message: Main actor-isolated operator function '==' cannot be used to satisfy nonisolated protocol requirement; this is an error in the Swift 6 language mode. Any suggestions? Thanks FB: FB15753655 (SwiftUI View cannot conform custom Equatable protocol in Swift 6.)
6
0
1k
Nov ’24
iOS 18.1 crash UIHostingView.layoutSubviews() / swift_unknownObjectWeakAssign / objc_storeWeak
We're seeing sporadic crashes on devices running iOS 18.1 - both beta and release builds (22B83). The stack trace is always identical, a snippet of it below. As you can tell from the trace, it's happening in places we embed SwiftUI into UIKit via UIHostingController. Anyone else seeing this? 4 libobjc.A.dylib 0xbe2c _objc_fatalv(unsigned long long, unsigned long long, char const*, char*) + 30 5 libobjc.A.dylib 0xb040 weak_register_no_lock + 396 6 libobjc.A.dylib 0xac50 objc_storeWeak + 472 7 libswiftCore.dylib 0x43ac34 swift_unknownObjectWeakAssign + 24 8 SwiftUI 0xeb74c8 _UIHostingView.base.getter + 160 9 SwiftUI 0x92124 _UIHostingView.layoutSubviews() + 112 10 SwiftUI 0x47860 @objc _UIHostingView.layoutSubviews() + 36
9
1
1.4k
Nov ’24
What's the best way to support Genmoji with SwiftUI?
I want to support Genmoji input in my SwiftUI TextField or TextEditor, but looking around, it seems there's no SwiftUI only way to do it? If none, it's kind of disappointing that they're saying SwiftUI is the path forward, but not updating it with support for new technologies. Going back, does this mean we can only support Genmoji through UITextField and UIViewRepresentable? or there more direct options? Btw, I'm also using SwiftData for storage.
1
1
766
Nov ’24
How can I make an "inverted" list (bottom to top) with SwiftUI?
I'm trying to figure out how to make an inverted list in my watchOS app for a message view, so that messages appear from the bottom first, and go up. Everything I've tried so far has some sort of major drawback, and I'm wondering if there's some proper way to do it. My current implementation is flipping every message item upside-down, then flipping the whole list upside-down. This works in making the list go from bottom to top, but the digital crown scroll direction is also inverted. Simply inverting the array of messages doesn't work either, as the user has to scroll to the bottom of the list manually every time. Any tips/suggestions would be greatly appreciated.
1
0
475
Nov ’24
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
444
Nov ’24
App Shortcuts: Invalid parameter type. AppEntity and AppEnum are the only allowed types...
Hi! So while Date is supported for @Parameter in an App Intent, I just discovered that Xcode will not let me use use it in a parametrized App Shortcut phrase. In my case, I would like to give the option to say "today", tomorrow", or "day after tomorrow" for the date. Am I missing something? Any hints on the best way to approach this?
6
1
1.1k
Dec ’24
Can I tell when my iOS Widget is running on MacOS (when Use IPhone Widgets is on)
I have an iOS Widget that also can load on the Mac when the Use iPhone Widgets setting is turned on on the Mac in Desktop & Dock. I want to use a different url scheme to open video clips from the widget if it is being clicked on iOS or the Mac. I tried using ProcessInfo.processInfo.isiOSAppOnMac but it always thinks it is on iOS. I also tried looking for the user document path to see if it was /var/mobile/ or /Users/. but it always thinks it is /var/mobile. I assume this is as it is not really a catalyst app but a WidgetKit extension from the phone. Is there anyway I can figure out when the widget is running on the mac? Thanks!
6
0
662
Dec ’24
Changing focus state in onSubmit causes keyboard to bounce
Is there any way to prevent the keyboard from bouncing when changing the focus state in onSubmit? Or is it not recommended to change focus in onSubmit? The following view is setup so that pressing return on the keyboard should cause focus to move between the TextFields. struct TextFieldFocusState: View { enum Field { case field1 case field2 } @FocusState var focusedField: Field? var body: some View { Form { TextField("Field 1", text: .constant("")) .focused($focusedField, equals: .field1) .onSubmit { focusedField = .field2 } TextField("Field 2", text: .constant("")) .focused($focusedField, equals: .field2) .onSubmit { focusedField = .field1 } } } } I would expect that when pressing return, the keyboard would say on screen. What actually happens is the keyboard appears to bounce when the return key is pressed (first half of gif). I assume this is because onSubmit starts dismissing the keyboard then setting the focus state causes the keyboard to be presented again. The issue doesn't occur when tapping directly on the text fields to change focus (second half of gif).
2
4
611
Dec ’24
Dock tile plugin and app groups
In one of my apps I use an app group to share data between the app and a command line tool. This works as expected. The app also contains a Dock Tile plugin and I wonder if there's a way to access the group container from this plugin? Thanks in advance for your help. Best regards, Marc
5
0
454
Dec ’24
Animated Custom Transitions Crash using Swift 6
When you apply an animation to a custom Transition in Swift 6, it is likely that that the app will crash with a SwiftUI.AsyncRenderer dispatch_assert_queue_fail error. Non-animated Transitions do not crash nor do animated system transitions. If you use ViewModifiers to create an AnyTransition with the .modifier(active:, identity:) static method, there is no problem. I used the example Transition in the docs for Transition to illustrate this problem. I'm using Xcode 16.2 RC and Swift 6, running iOS 18.1.1 on an iPhone 16 Pro. I've created two separate Previews that illustrate what specifically crashes the app and what doesn't as well as a workaround for this bug. func generateRandomString() -> String { let characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" return String((0..<10).compactMap { _ in characters.randomElement() }) } // MARK: Works extension AnyTransition { struct RotatingFadeTransitionModifier: ViewModifier { let opacity: CGFloat let rotation: Angle func body(content: Content) -> some View { content .opacity(opacity) .rotationEffect(rotation) } } static var rotatingFade: AnyTransition { .asymmetric( insertion: .modifier( active: RotatingFadeTransitionModifier(opacity: 0, rotation: .degrees(30)), identity: RotatingFadeTransitionModifier(opacity: 1, rotation: .zero) ), removal: .modifier( active: RotatingFadeTransitionModifier(opacity: 0, rotation: .degrees(-30)), identity: RotatingFadeTransitionModifier(opacity: 1, rotation: .zero) ) ) } } struct WorkingTransitionView: View { @State private var text: String = "some string" var body: some View { VStack(spacing: 32) { Text("system transition: \(text)") .id(text) .transition(.slide) // Gets the explicit Button animation applied instead of // the transition animation Text("animated system transition: \(text)") .id(text) .transition(.slide.animation(.bouncy(duration: 0.5))) Text("custom transition: \(text)") .id(text) .transition(.rotatingFade) Text("animated custom transition: \(text)") .id(text) .transition(.rotatingFade.animation(.bouncy( extraBounce: 0.5))) Button("animated randomize - safe") { withAnimation(.smooth(duration: 5.45, extraBounce: 0.15)) { text = generateRandomString() } } } } } // MARK: Crashes struct RotatingFadeTransition: Transition { func body(content: Content, phase: TransitionPhase) -> some View { content .opacity(phase.isIdentity ? 1.0 : 0.0) .rotationEffect(phase.rotation) } } extension TransitionPhase { fileprivate var rotation: Angle { switch self { case .willAppear: .degrees(30) case .identity: .zero case .didDisappear: .degrees(-30) } } } struct CrashingTransitionView: View { @State private var text: String = "some string" @State private var presentCustomTransitionText: Bool = false @State private var presentAnimatedCustomTransitionText: Bool = false var body: some View { VStack(spacing: 32) { Text("on 1-5 attempts generally, animated custom Transitions will crash with a SwiftUI.AsyncRenderer dispatch_assert_queue_fail") Divider() textWithSafeSystemTransition if presentCustomTransitionText { textWithCustomTransition } if presentAnimatedCustomTransitionText { textWithAnimatedCustomTransition } Divider() Text("Randomization") Button("randomize - won't crash non-animated custom transition text") { text = generateRandomString() } Button("animated randomize - will crash any custom transition text") { withAnimation(.smooth(duration: 0.45, extraBounce: 0.15)) { text = generateRandomString() } } Divider() Text("Text Presentation") Button("present non-animated custom transition text") { presentCustomTransitionText = true } Button("present animated custom transition text") { presentAnimatedCustomTransitionText = true } } } private var textWithSafeSystemTransition: some View { Text("safe, system transition: \(text)") .id(text) .transition(.slide) } private var textWithCustomTransition: some View { Text("safe text, custom transition: \(text)") .id(text) .transition(RotatingFadeTransition()) } private var textWithAnimatedCustomTransition: some View { Text("crashing text: \(text)") .id(text) .transition(RotatingFadeTransition().animation(.smooth)) } } #Preview("Working Code") { WorkingTransitionView() } #Preview("Crashing Code") { CrashingTransitionView() }
3
1
565
Dec ’24
button is pressed when starting scrolling in iOS 18
On iOS 18, while on a modal screen, if the scrolling starts on a button, that button gets pressed, outside of a modal this doesn't reproduce, also not reproducible on older iOS versions, neither on modals or outside of them. The code to reproduce the issue: import SwiftUI struct ContentView: View { @State var presentModal = false var body: some View { Button(action: { presentModal = true }, label: { Text("open modal") }) .sheet(isPresented: $presentModal, content: { ScrollView { ForEach(0..<100, id: \.self) { index in Button(action: { print("Button \(index) tapped!") }) { Text("Button \(index)") .frame(maxWidth: .infinity) .frame(height: 100) .background(randomColor(for: index)) .padding(.horizontal) } } } }) } func randomColor(for index: Int) -> Color { let hue = Double(index % 100) / 100.0 return Color(hue: hue, saturation: 0.8, brightness: 0.8) } } #Preview { ContentView() }
7
6
759
Dec ’24