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

How can I use specify the anchor used to display an item that a user scrolls to ?
I have a scrollview displaying a sequence of circles, which a user should be able to scroll through to select an item. When the user stops scrolling and the animation comes to rest the circle selected should display screen-centered. I had hoped to achieve this using .scrollPosition(id: selectedItem, anchor: .center) but it appears that the anchor argument is ignored when scrolled manually. (BTW - I searched but didn't locate this aspect in the Apple documentation so I'm not confident that this observation is really correct). https://youtu.be/TpXDTuL5yPQ The video shows the user-scrolling behaviour, and also the snap-to-anchor that I would like to achieve, but I would like this WITHOUT forcing a button press. I could juggle the container size and size of the circles so that they naturally fit centered into the screen, but I would prefer a more elegant solution. How can I force the scrolling to come to rest such that the circle glides to rest in the center of the screen/container? struct ItemChooser: View { @State var selectedItem: Int? var body: some View { VStack { Text("You have picked: \(selectedItem ?? 0)") ScrollHorizontalItemChooser(selectedItem: $selectedItem) } } } #Preview { ItemChooser(selectedItem: 1) } struct ScrollHorizontalItemChooser: View { @Binding var selectedItem: Int? @State var scrollAlignment: UnitPoint? = .center let ballSize: CGFloat = 150 let items = Array(1...6) @State var scrollPosition: ScrollPosition = ScrollPosition() var body: some View { VStack { squareUpButton ScrollView(.horizontal) { HStack(spacing: 10) { showBalls } .scrollTargetLayout() } .scrollPosition(id: $selectedItem, anchor: scrollAlignment ) .overlay{ crosshairs } } } var crosshairs: some View { Image(systemName: "scope").scaleEffect(3.0).opacity(0.3) } @ViewBuilder var showBalls: some View { let screenWidth: CGFloat = UIScreen.main.bounds.width var emptySpace: CGFloat {screenWidth / 2 - ballSize / 2 - 10} Spacer(minLength: emptySpace) ForEach(items, id: \.self) { item in poolBall( item) .id(item) } Spacer(minLength: emptySpace) } @ViewBuilder private func poolBall(_ item: Int) -> some View { Text("Item \(item)") .background { Circle() .foregroundColor(Color.green) .frame(width: ballSize, height: ballSize) } .frame(width: ballSize, height: ballSize) } @ViewBuilder var squareUpButton: some View { var tempSelected: Int? = nil Button("Square up with Anchor") { tempSelected = selectedItem selectedItem = 0 DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { selectedItem = tempSelected ?? 0 } } } }
Topic: UI Frameworks SubTopic: SwiftUI
1
0
239
Mar ’25
SwiftUI SimultaneousGesture with RotateGesture and MagnifyGesture fails if only one gesture is recognized
I'm trying to combine a RotateGesture and a MagnifyGesture within a single SwiftUI view using SimultaneousGesture. My goal is to allow users to rotate and zoom an image (potentially at the same time). However, I’m running into a problem: If only one gesture (say, the magnification) starts and finishes without triggering the other (rotation), it seems that the rotation gesture is considered "failed." After that, no further .onChanged or .onEnded callbacks fire for either gesture until the user lifts their fingers and starts over. Here’s a simplified version of my code: struct ImageDragView: View { @State private var scale: CGFloat = 1.0 @State private var lastScale: CGFloat = 1.0 @State private var angle: Angle = .zero @State private var lastAngle: Angle = .zero var body: some View { Image("Stickers3") .resizable() .aspectRatio(contentMode: .fit) .frame(height: 100) .rotationEffect(angle, anchor: .center) .scaleEffect(scale) .gesture(combinedGesture) } var combinedGesture: some Gesture { SimultaneousGesture( RotateGesture(minimumAngleDelta: .degrees(8)), MagnifyGesture() ) .onChanged { combinedValue in if let magnification = combinedValue.second?.magnification { let minScale = 0.2 let maxScale = 5.0 let newScale = magnification * lastScale scale = max(min(newScale, maxScale), minScale) } if let rotation = combinedValue.first?.rotation { angle = rotation + lastAngle } } .onEnded { _ in lastScale = scale lastAngle = angle } } } If I pinch and rotate together (or just rotate), both gestures work as expected. But if I only pinch (or, sometimes, if the rotation amount doesn’t meet minimumAngleDelta), subsequent gestures don’t trigger the .onChanged or .onEnded callbacks anymore, as if the entire gesture sequence is canceled. I found that setting minimumAngleDelta: .degrees(0) helps because then rotation almost never fails. But I’d like to understand why this happens and whether there’s a recommended way to handle the situation where one gesture might be recognized but not the other, without losing the gesture recognition session entirely. Is there a known workaround or best practice for combining a pinch and rotate gesture where either one might occur independently, but we still want both gestures to remain active? Any insights would be much appreciated!
1
0
273
Mar ’25
ShareLink of a movie is inconsistent
In my app, I have a ShareLink that attempts to share a movie. struct MovieTransferable: Transferable { let url: URL let writeMovie: (URL) -> () static var transferRepresentation: some TransferRepresentation { DataRepresentation( exportedContentType: .movie, exporting: { (movie) in // Write the movie into documents. movie.writeMovie(movie.url) return try! Data(contentsOf: movie.url) }) FileRepresentation( exportedContentType: .movie, exporting: { (movie) in // Write the movie into documents. movie.writeMovie(movie.url) return SentTransferredFile(movie.url) }) } } The ShareLink works if you try to share the movie with the Photos app, Air Drop, and iMessage. If I share to WhatsApp, the movie shows up as empty (zero length), but there's a movie. If I share to Discord, the movie is not displayed at all (only the comment). Instagram posts a dialog saying it won't allow movies and to use the app (why are they even in the ShareLink option for movies?). YouTube processes for a bit and then does nothing (no upload). Are there things that I can do to make the Transferable accepted at more of the end points? It's at fps 30 and I've tried most of the available codec's. The size is the same as the iPhone's screen, so the aspect ratio is a bit odd. However, if I go directly to the app (Discord, etc...) upload from my phone works fine. Any help would be appreciated to make this more viable.
2
0
381
Mar ’25
UITabbarController issue on iOS 18
I'm building an app using UITabbarController with 2 tabs: screen A and B. When standing on tab B and I taps on tab A, the order in which the events are triggered will be: For iOS < 18: viewWillDisappear() of screen B tabBarController(_:didSelect:) of UITabbarController For iOS >= 18: tabBarController(_:didSelect:) of UITabbarController viewWillDisappear() of screen B So my question is this an issue or a new update from Apple on iOS 18.*?
Topic: UI Frameworks SubTopic: UIKit Tags:
2
0
394
Mar ’25
Release Build Configuration as Release Fails Preview
I have a simple SwiftUI project with two basic build configurations (Debug, Release) as shown below. I now choose Build > Scheme > Edit Scheme under Product and select Release as the current build configuration as shown below. And the Preview canvas exhibit errors. If I click on the Diagnostics button, it says under PREVIEW UPDATE ERROR OptimizationLevelError: not building -Onone ”BuildSchemeCrazyDaughter.app” needs -Onone Swift optimization level to use previews (current setting is -O) What does that mean and why don't I get the preview for the Release build configuration? Thanks.
1
0
200
Mar ’25
Unexpected UINavigationController setViewControllers Behavior on iOS 18.2 During Animated Transitions
Hello everyone, I've run into a peculiar behavior with UINavigationController's setViewControllers on iOS 18.2 (I guess it might be reproducible on older versions) when reordering view controllers, and I wonder if anyone can shed some light on this issue. Initial State: The navigation stack is [A - B - C]. Without Animation: Setting [A - C - B] updates the stack to: A - C - B as expected. With Animation: Using the same command with animation changes the stack to [A - B], oddly omitting C. Has anyone else noticed similar behavior or knows why animations might disrupt the stack's update this way? I'd appreciate any insights or suggestions. Thanks, Dmytro
1
0
369
Mar ’25
Hover effect is shown on a disabled button
Hello. I have a scenario where a hover effect is being shown for a button that is disabled. Usually this doesn't happen but when you wrap the button in a Menu it doesn't work properly. Here is some example code: struct ContentView: View { var body: some View { NavigationStack { Color.green .toolbar { ToolbarItem(placement: .topBarTrailing) { Menu("Menu") { Button("Disabled Button") {} .disabled(true) .hoverEffectDisabled() // This doesn't work. Button("Enabled Button") {} } } } } } } And here is what it looks like: This looks like a SwiftUI bug. Any help is appreciated, thank you!
1
0
270
Feb ’25
BUG: screen flicker on quick tap / swipe to go back
I have found a system bug with UINavigationController, UIGestureRecognizerDelegate mainly the swipe back control. I have reproduced this in many apps, while some that use custom swipe back i can not reproduce, however any app using default uikit/swift transitions i can reproduce the flicker/previous screen flashing The Bug: a slight tap or series of quick taps anywhere on the screen (with the slightest (1-2pt -x)confuse the system into thinking its a swipe back gesture, however instead of pushing back to previous screen the UI flickers and flashes the previous screen. for a split second, very easy to reproduce. on screens with lots of options of boxes to tap it happens quite often. I have removed all custom "swipe back from anywhere" logic, all custom gesture logic, and can still reproduce by tapping the edge of the screen with only UINavigationController, UIGestureRecognizerDelegate in my navigation controller. Please let me know the best way to get in contact with someone at apple to either build an extension to prevent this flicker or if a developer has a fix but this is rarely talked about. (velocity limits etc do not work, and just make the gesture feel awful) all the developers i have reached out too have looked into this and have said "its an ios bug, only fix is build a custom swipe back from anywhere, or wait for apple to fix it).... as a small indie app, building my own seems daunting Recap: quick or taps with small x movement flash previous screen instead of pushing back or simply recognizing it as a tap and not flashing previous screen. this happens with no custom code default uikit/swift. Link me your app i can probably reproduce it, I have reproduced it in X(was hard), Retro(easy), and many more. The goal is to have a smooth native swipe/drag back from anywhere gesture while preventing flicking on fast taps or short taps with minor x movement. i have tried everything from setting limits to -x, velocity limits etc. nothing fixes this. happy hacking! PS i hope someone at apple calls me and i can explain this and we can fix it for every app in an update.
2
0
554
Mar ’25
What happened to readable margins?
Am in the process of migrating some UIKit based apps over to SwiftUI, but for the life of me I cannot find the SwiftUI equivalent of Readable Content Margins. I have come across some workarounds that kind of, sort of work, but do not produce the same results when compared to running the same user interface written using UIKit on several sizes of iPads in portrait and landscape orientiations. is it something Apple has not gotten around to yet, because I realize SwiftUI is a work-in-progress, or do we not care about creating consistent readable margins in our apps anymore?
2
0
325
Mar ’25
How to override NSWindow in a pure SwiftUI Application
So I am looking to use a custom NSWindow application (so I can implement some enhanced resizing/dragging behavior which is only possible overriding NSWindow). The problem is my whole application is currently SwiftUI-based (see the project here: https://github.com/msdrigg/Roam/blob/50a2a641aa5f2fccb4382e14dbb410c1679d8b0c/Roam/RoamApp.swift). I know there is a way to make this work by dropping my @main SwiftUI app and replacing it with a SwiftUI root view hosted in a standard AppKit root app, but that feels like I'm going backwards. Is there another way to get access (and override) the root NSWindow for a SwiftUI app?
0
0
297
Mar ’25
Crash on removal of QLPreviewController and _EXRemoteViewController
I have a controller that displays a pdf using UIDocumentInteractionController as the presented view. When users open it up, it shows fine. User gets the app backgrounded and session timed out. After timed out, when the app is brought to foreground, I bring our loginVC by removing the old VC used to show the UIDocumentInteractionController. All the crashes are happening at this point. I am not able to reproduce it, but our alert systems show we have crashes happening. The code that shows the pdf is straight forward documentViewController = UIDocumentInteractionController() documentViewController?.delegate = self documentViewController?.url = url documentViewController?.presentPreview(animated: true) and we reset it to nil in delegate documentInteractionControllerDidEndPreview Based on the crash trace, it seems like the crash happens when our login VC replaces it and only when pdf was displayed. The reason of stressing ONLY because when we have other viewcontroller present and they are removed in a similar way, we do not see any issue. So we always replace first and then add a new one childViewController.willMove(toParent: nil) childViewController.viewIfLoaded?.removeFromSuperview() childViewController.removeFromParent() addChild(childViewController) view.addSubview(childViewController.view) childViewController.view.frame = view.bounds childViewController.didMove(toParent: self) Raised a ticket with Apple, but I haven't heard back, and it's been a month. Posting here in case anyone experiences the same and has any solutions. I saw some related posts, and solution was to remove the pdf the moment the app goes to the background, but I am trying to find some alternate solution if possible.
Topic: UI Frameworks SubTopic: UIKit
0
0
220
Mar ’25
Closure with typed throws stored as a View property crashes on iOS 17
I've encountered an issue where storing a throws(PermissionError) closure as a property inside a SwiftUI View causes a runtime crash on iOS 17, while it works correctly on iOS 18. Here’s an example of the affected code: enum PermissionError: Error { case denied } struct PermissionCheckedView<AllowedContent: View, DeniedContent: View>: View { var protectedView: () throws(PermissionError) -> AllowedContent var deniedView: (PermissionError) -> DeniedContent init( @ViewBuilder protectedView: @escaping () throws(PermissionError) -> AllowedContent, @ViewBuilder deniedView: @escaping (PermissionError) -> DeniedContent ) { self.protectedView = protectedView self.deniedView = deniedView } public var body: some View { switch Result(catching: protectedView) { case .success(let content): content case .failure(let error): deniedView(error) } } } @main struct TestApp: App { var body: some Scene { WindowGroup { PermissionCheckedView { } deniedView: { _ in } } } } Specifically this is the stack trace (sorry for the picture I didn't know how to get the txt): If I use var protectedView: () throws -> AllowedContent without typed throws it works.
2
0
300
Feb ’25
Document-based app failing in Mac Catalyst
A document-based app that's been running fine on iPad and Mac Catalyst has stopped working on the Mac as of Sequoia 15.3. After the user selects a document to open, my app never gets called back from Apple's framework. (The app works fine on iPadOS.) Anybody else see this? I filed a feedback, FB16506048, several weeks ago but have had no reply.
Topic: UI Frameworks SubTopic: SwiftUI
1
0
190
Mar ’25
alternateIconName
I config of an alternate icon on the App Store Connect product page optimization. After the app launches, can I retrieve the name of this configured icon through UIApplication.shared.alternateIconName?
1
0
301
Mar ’25
An unresolvable crash.
My app is experiencing a recurring crash in the PRD environment, but it cannot be reproduced locally or in QA testing. Below is the crash log—I’d appreciate any help or insights on how to diagnose and resolve this issue. Thank you! 0 libobjc.A.dylib 0x2354 objc_release_x0 + 16 1 libobjc.A.dylib 0x2354 objc_release + 16 2 libobjc.A.dylib 0x4e38 AutoreleasePoolPage::releaseUntil(objc_object**) + 204 3 libobjc.A.dylib 0x4b8c objc_autoreleasePoolPop + 260 4 FrontBoardServices 0x1f4d0 -[FBSWorkspace _calloutQueue_executeCalloutFromSource:withBlock:] + 176 5 FrontBoardServices 0x2eb90 -[FBSWorkspaceScenesClient _callOutQueue_sendDidCreateForScene:transitionContext:completion:] + 468 6 libdispatch.dylib 0x3fa8 _dispatch_client_callout + 20 7 libdispatch.dylib 0x79f0 _dispatch_block_invoke_direct + 284 8 FrontBoardServices 0x18378 __FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 52 9 FrontBoardServices 0x182f8 -[FBSMainRunLoopSerialQueue _targetQueue_performNextIfPossible] + 240 10 FrontBoardServices 0x181d0 -[FBSMainRunLoopSerialQueue _performNextFromRunLoopSource] + 28 11 CoreFoundation 0x73f3c __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 28 12 CoreFoundation 0x73ed0 __CFRunLoopDoSource0 + 176 13 CoreFoundation 0x76b94 __CFRunLoopDoSources0 + 344 14 CoreFoundation 0x75d2c __CFRunLoopRun + 840 15 CoreFoundation 0xc8274 CFRunLoopRunSpecific + 588 16 GraphicsServices 0x14c0 GSEventRunModal + 164 17 UIKitCore 0x3ee77c -[UIApplication _run] + 816 18 UIKitCore 0x14e64 UIApplicationMain + 340
Topic: UI Frameworks SubTopic: UIKit
2
0
320
Feb ’25
UITextView in SwiftUI Not Scrolling to Position When Becoming First Responder
I'm implementing a custom text editor in SwiftUI using a UITextView wrapped in a UIViewRepresentable. The text editor works for basic text entry, but I'm encountering an issue with scrolling behavior. When the UITextView becomes the first responder (when tapped), the parent ScrollView doesn't automatically scroll to make the text view visible. Instead, the scroll position jumps to the last known position (scrolls to a different text view that was previously focused). Here's my implementation reduced to the minimum: struct SpacedTextEditor: View { @Binding var text: String var body: some View { MinimalEditor(text: $text) } } private struct MinimalEditor: UIViewRepresentable { @Binding var text: String func makeUIView(context: Context) -> UITextView { let textView = UITextView() textView.backgroundColor = .clear textView.delegate = context.coordinator textView.isScrollEnabled = false textView.text = text return textView } func updateUIView(_ textView: UITextView, context _: Context) { if textView.text != text { textView.text = text } } func makeCoordinator() -> Coordinator { Coordinator(text: $text) } class Coordinator: NSObject, UITextViewDelegate { var text: Binding<String> init(text: Binding<String>) { self.text = text } func textViewDidChange(_ textView: UITextView) { text.wrappedValue = textView.text } } } The text editor is placed inside a ScrollView in my parent view. How can I ensure that when a user taps on the text editor, the ScrollView properly scrolls to make it fully visible or at least it doesn't jump to where the textfield is not even visible? I need to use a custom textfield because I need to be able to modify the space between lines, and I didn't find a way to do this using the swiftUI component.
Topic: UI Frameworks SubTopic: SwiftUI
1
0
103
Mar ’25