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

Abnormal UI and Keyboard Behavior in iPhone App Running on iPadOS 18.x Built with Xcode 16
Case-ID: 12591306 Use Xcode 16.x to compile an iPhone demo app and run it on an iPad (iPadOS 18.x) device or simulator. Launch the iPhone app and activate Picture-in-Picture mode. Attempt to input text; the system keyboard does not appear. Compare the output of [[UIScreen mainScreen] bounds] before and after enabling Picture-in-Picture mode, notice the values change unexpectedly after enabling PiP. This issue can be consistently reproduced on iPadOS 18.x when running an app built with Xcode 16.0 to Xcode 16.3RC(16E137). Beginning April 24, 2025, apps uploaded to App Store Connect must be built with Xcode 16 or later using an SDK for iOS 18, iPadOS 18, tvOS 18, visionOS 2, or watchOS 11.Therefore, I urgently hope to receive a solution provided by Apple.
1
0
147
Mar ’25
MacOS Scale to view
on iOS you can choose to scale to view to have the app resize the screen easily in the developer environment. Scale to view is however not easily done on MacOS using NS to solve on MacOS now. Is it possible for the Apple developer team to make this easier for the Developer, as I understand it is for iOS applications?
0
0
275
Feb ’25
Avoiding logoff when installing new/modified InputMethodKit input source
It appears that on all recent versions of macOS when adding a new InputSource in /Library/Input Methods (or modifying an existing one there) the user needs to logoff and log back in in order for Keyboard/Input Sources in System Settings and Input Menu in menu bar to pick up the changes. Is there a way to avoid this? That is, some notification to send or API to call to tell both of these "hey, things might have changed on disk, please re-read the info, and update the UI". 🙂
1
0
274
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
299
Mar ’25
`.refreshable(action:)` `s indicator will not dismiss after when app into backgound (iOS 17.1)
Hello, I am encountering an issue with .refreshable(action:) in ScrollView. The refresh action works as expected when performing a pull-to-refresh. However, if I put the app in the background while the refresh operation is in progress, the refresh indicator remains visible on the screen when I return to the foreground and does not disappear. Once I interact with the ScrollView after returning to the foreground, the refresh indicator disappears, and the functionality itself is not affected. I initially attempted to resolve this issue by triggering a view redraw when scenePhase changes. However, since my app presents the SwiftUI view using UIHostingController, the scenePhase from the environment does not seem to function correctly. This issue occurs on iOS 17.1 but does not appear on iOS 16.1.1. Is there a known way to resolve this unexpected behavior? Below is a simplified sample code (some parts are omitted): struct MyView: View { @StateObject private var model: MyModel var body: some View { ScrollView { // My ContentViews... } .refreshable { do { try await self.model.refresh() } catch { // Handle error } } } } @MainActor final class MyModel: ObservableObject { // === Some Code === func refresh() async throws { let data = try await self.fetchData() self.data = Array(OrderedSet(data)) } } I apologize for any mistakes in my English, as I am using a translation tool. Thank you in advance for your help! Best regards,
1
0
207
Mar ’25
SwiftData predicate for many to many relationships?
Hello, I have a Task model in my application which has an optional many to many relationship to a User model. task.assignedUsers user.tasks I am looking to construct a SwiftData predicate to fetch tasks which either have no assigned users or assigned users does not contain specific user. Here is a partially working predicate I have now: static func assignedToOthersPredicate() -> Predicate<Task> { let currentUserGUID = User.currentUserGUID return #Predicate<Task> { task in task.assignedUsers.flatMap { users in users.contains(where: { $0.guid != currentUserGUID }) } == true } } This only returns tasks assigned to others, but not those which have no assigned users. If combine it with this: static func notAssignedPredicate() -> Predicate<Task> { return #Predicate<Task> { task in task.assignedUsers == nil } } Then I get a run time crash: "to-many key not allowed here" What is the proper way to do this? Thanks.
1
0
352
Mar ’25
Correct way to run modal session?
My assumption has always been that [NSApp runModalForWindow:] runs a modal window in NSModalPanelRunLoopMode. However, while -[NSApplication _doModalLoop:peek:] seems to use NSModalPanelRunLoopMode when pulling out the next event to process via nextEventMatchingMask:untilDate:inMode:dequeue:, the current runloop doesn't seem to be running in that mode, so during -[NSApplication(NSEventRouting) sendEvent:] of the modal-specific event, NSRunLoop.currentRunLoop.currentMode returns kCFRunLoopDefaultMode. From what I can tell, this means that any event processing code that e.g. uses [NSTimer addTimer:forMode:] based on the current mode will register a timer that will not fire until the modal session ends. Is this a bug? Or if not, is the correct way to run a modal session something like this? [NSRunLoop.currentRunLoop performInModes:@[NSModalPanelRunLoopMode] block:^{ [NSApp runModalForWindow:window]; }]; [NSRunLoop.currentRunLoop limitDateForMode:NSModalPanelRunLoopMode]; Alternatively, if the mode of the runloop should stay the same, I've seen suggestions to run modal sessions like this: NSModalSession session = [NSApp beginModalSessionForWindow:theWindow]; for (;;) { if ([NSApp runModalSession:session] != NSModalResponseContinue) break; [NSRunLoop.currentRunLoop limitDateForMode:NSModalPanelRunLoopMode]; } [NSApp endModalSession:session]; Which would work around the fact that the timer/callbacks were scheduled in the "wrong" mode. But running NSModalPanelRunLoopMode during a modal session seems a bit scary. Won't that potentially break the modality?
0
0
106
Mar ’25
SWIFTUI: chartLegend alignment 'Centering' option
SWIFTUI : Chart control / view is there way to align the Legends to align the center I see there only 2 options, .chartLegend(position: .bottom, alignment: .leading,spacing: 10) .leading or .trailing code : Chart{ ..... SectorMark.. } .chartLegend(position: .bottom, alignment: .leading,spacing: 10)
Topic: UI Frameworks SubTopic: SwiftUI
2
0
284
Mar ’25
Hover effect in Custom UIKit Views
I am adapting my custom UI Framework for visionOS, and I'm wondering if it is going to be possible to detect hover over different UI elements within my view. The UI Framework draws to a Metal layer in a UIView. I don't currently support uihovergesturerecognizer on the view but I guess this wouldn't help, since you don't get coordinates. I can imagine an unpleasant solution might be to add invisible UIControls for each of my custom controls that are drawn in my own framework.
1
0
61
Apr ’25
How do you pass a view builder into a view?
I'm making a custom control, specifically a checkbox next to a "label." I want the label parameter, like many in Apple's built-in controls, to take a view-building closure. But I can't figure out the correct syntax. I looked at the declaration of Apple's NavigationLink control for clues: public struct NavigationLink<Label, Destination> : View where Label : View, Destination : View { /// Creates a navigation link that presents the destination view. /// - Parameters: /// - destination: A view for the navigation link to present. /// - label: A view builder to produce a label describing the `destination` /// to present. public init(@ViewBuilder destination: () -> Destination, @ViewBuilder label: () -> Label) But when I mimic this, the compiler complains about the body() function: struct CheckboxItem<Label> : View where Label : View { let stateCheck: () -> Bool let label: () -> any View let boxSize: CGFloat init(withStateCheck: @escaping () -> Bool, boxSize: CGFloat, @ViewBuilder label: @escaping () -> Label) { stateCheck = withStateCheck self.label = label self.boxSize = boxSize } var body: some View { HStack { <-- ERROR: "Type 'any View' cannot conform to 'View'" Image(systemName: stateCheck() ? "checkmark.square" : "square") .resizable() .aspectRatio(contentMode: .fit) .frame(width: boxSize, height: boxSize) .foregroundColor(AppStyle.labelColor) .opacity(0.75) label() } } } Also, note that I had to put @escaping before my label parameter, but that's not seen in Apple's. Any ideas?
Topic: UI Frameworks SubTopic: SwiftUI
1
0
213
Mar ’25
progress view does not work
I have an app that run Monte Carlo simulations. I run thousands of simulations in the app and a simulation runs can take on the order of 30 seconds to a minute to complete. I would like to have a progress view that tracks the number of simulation runs. How can I implement this in swiftui?
0
0
174
Mar ’25
Trying to drag a modelEntity inside an Immersive space
Goal : Drag a sphere across the room and track it's position Problem: The gesture seems to have no effect on the sphere ModelEntity. I don't know how to properly attach the gesture to the ModelEntity. Any help is great. Thank you import SwiftUI import Foundation import UIKit @main struct testApp: App { @State var immersionStyle:ImmersionStyle = .mixed var body: some Scene { ImmersiveSpace { ContentView() } .immersionStyle(selection: $immersionStyle, in: .mixed, .full, .progressive) } } struct ContentView: View { @State private var lastPosition: SIMD3? = nil @State var subscription: EventSubscription? @State private var isDragging: Bool = false var sphere: ModelEntity { let mesh = MeshResource.generateSphere(radius: 0.05) let material = SimpleMaterial(color: .blue, isMetallic: false) let entity = ModelEntity(mesh: mesh, materials: [material]) entity.generateCollisionShapes(recursive: true) return entity } var drag: some Gesture { DragGesture() .onChanged { _ in self.isDragging = true } .onEnded { _ in self.isDragging = false } } var body: some View { RealityView { content in //1. Anchor Entity let anchor = AnchorEntity(world: SIMD3<Float>(0, 0, -1)) let ball = sphere //2. add anchor to sphere anchor.addChild(ball) content.add(anchor) subscription = content.subscribe(to: SceneEvents.Update.self) { event in let currentPosition = ball.position(relativeTo: nil) if let last = lastPosition, last != currentPosition { print("Sphere moved from \(last) to \(currentPosition)") } lastPosition = currentPosition } } .gesture(drag) } }
1
0
75
Apr ’25
App crashes after multiple transitions to screen containing AR Kit using SwiftUI NavigationStack
Hello. I am currently building an app using AR Kit. As for the UI, I am using SwiftUI and NavigationStack + NavigationLink for navigation and screen transitions! Here I need to go back and forth between the AR screen and other screens. If the number of screen transitions is small, this is not a problem. However, if the number of screen transitions increases to 10 or 20, it crashes somewhere. We are struggling with this problem. (The nature of the application requires multiple screen transitions.) The crash log showed the following. error: read memory from 0x1e387f2d4 failed AR_Crash_Sample-2025-03-07-115914.txt Incident Identifier: B23D806E-D578-4A95-8828-2A1E8D6BB7F8 Beta Identifier: 924A85AB-441C-41A7-9BC2-063940BDAF32 Hardware Model: iPhone16,1 Process: AR_Crash_Sample [2375] Path: /private/var/containers/Bundle/Application/FAC3D662-DB10-434E-A006-79B9515D8B7A/AR_Crash_Sample.app/AR_Crash_Sample Identifier: ar.crash.sample.AR.Crash.Sample Version: 1.0 (1) AppStoreTools: 16C7015 AppVariant: 1:iPhone16,1:18 Beta: YES Code Type: ARM-64 (Native) Role: Foreground Parent Process: launchd [1] Coalition: ar.crash.sample.AR.Crash.Sample [1464] Date/Time: 2025-03-07 11:59:14.3691 +0900 Launch Time: 2025-03-07 11:57:47.3955 +0900 OS Version: iPhone OS 18.3.1 (22D72) Release Type: User Baseband Version: 2.40.05 Report Version: 104 Exception Type: EXC_CRASH (SIGABRT) Exception Codes: 0x0000000000000000, 0x0000000000000000 Termination Reason: SIGNAL 6 Abort trap: 6 Terminating Process: AR_Crash_Sample [2375] Triggered by Thread: 7 Application Specific Information: abort() called Thread 7 name: Dispatch queue: com.apple.arkit.depthtechnique Thread 7 Crashed: 0 libsystem_kernel.dylib 0x1e387f2d4 __pthread_kill + 8 1 libsystem_pthread.dylib 0x21cedd59c pthread_kill + 268 2 libsystem_c.dylib 0x199f98b08 abort + 128 3 libc++abi.dylib 0x21ce035b8 abort_message + 132 4 libc++abi.dylib 0x21cdf1b90 demangling_terminate_handler() + 320 5 libobjc.A.dylib 0x18f6c72d4 _objc_terminate() + 172 6 libc++abi.dylib 0x21ce0287c std::__terminate(void (*)()) + 16 7 libc++abi.dylib 0x21ce02820 std::terminate() + 108 8 libdispatch.dylib 0x199edefbc _dispatch_client_callout + 40 9 libdispatch.dylib 0x199ee65cc _dispatch_lane_serial_drain + 768 10 libdispatch.dylib 0x199ee7158 _dispatch_lane_invoke + 432 11 libdispatch.dylib 0x199ee85c0 _dispatch_workloop_invoke + 1744 12 libdispatch.dylib 0x199ef238c _dispatch_root_queue_drain_deferred_wlh + 288 13 libdispatch.dylib 0x199ef1bd8 _dispatch_workloop_worker_thread + 540 14 libsystem_pthread.dylib 0x21ced8680 _pthread_wqthread + 288 15 libsystem_pthread.dylib 0x21ced6474 start_wqthread + 8 Perhaps I am using too much memory! How can I address this phenomenon? For the AR functionality, we are using UIViewRepresentable, which is written in UIKit and can be called from SwiftUI import ARKit import AsyncAlgorithms import AVFoundation import SCNLine import SwiftUI internal struct MeasureARViewContainer: UIViewRepresentable { @Binding var tapCount: Int @Binding var distance: Double? @Binding var currentIndex: Int var focusSquare: FocusSquare = FocusSquare() let coachingOverlay: ARCoachingOverlayView = ARCoachingOverlayView() func makeUIView(context: Context) -> ARSCNView { let arView: ARSCNView = ARSCNView() arView.delegate = context.coordinator let configuration: ARWorldTrackingConfiguration = ARWorldTrackingConfiguration() configuration.planeDetection = [.horizontal, .vertical] if ARWorldTrackingConfiguration.supportsFrameSemantics(.sceneDepth) { configuration.frameSemantics = [.sceneDepth, .smoothedSceneDepth] } arView.session.run(configuration, options: [.resetTracking, .removeExistingAnchors]) context.coordinator.sceneView = arView context.coordinator.scanTarget() coachingOverlay.session = arView.session coachingOverlay.delegate = context.coordinator coachingOverlay.goal = .horizontalPlane coachingOverlay.activatesAutomatically = true coachingOverlay.autoresizingMask = [.flexibleWidth, .flexibleHeight] coachingOverlay.translatesAutoresizingMaskIntoConstraints = false arView.addSubview(coachingOverlay) return arView } func updateUIView(_ _: ARSCNView, context: Context) { context.coordinator.mode = MeasurementMode(rawValue: currentIndex) ?? .width if tapCount == 0 { context.coordinator.resetMeasurement() return } if distance != nil { return } DispatchQueue.main.async { if context.coordinator.distance == nil { context.coordinator.handleTap() } } } static func dismantleUIView(_ uiView: ARSCNView, coordinator: Coordinator) { uiView.session.pause() coordinator.stopScanTarget() coordinator.stopSpeech() DispatchQueue.main.async { uiView.removeFromSuperview() } } func makeCoordinator() -> Coordinator { Coordinator(self) } class Coordinator: NSObject, ARSCNViewDelegate, ARSessionDelegate, ARCoachingOverlayViewDelegate { var parent: MeasureARViewContainer var sceneView: ARSCNView? var startPosition: SCNVector3? var pointedCount: Int = 0 var distance: Float? var mode: MeasurementMode = .width let synthesizer: AVSpeechSynthesizer = AVSpeechSynthesizer() var scanTargetTask: Task<Void, Never>? var currentResult: ARRaycastResult? init(_ parent: MeasureARViewContainer) { self.parent = parent } // ... etc } }
2
0
352
Mar ’25
Label from ApplicationToken Inside of DeviceActivityReport Not Showing
tl;dr can we use Label(application token) inside of a DeviceActivityReport? I’m working on an app that uses the DeviceActivityReport extension to show a user’s screen time breakdown. The app was working fine in a setup where my main app had the Distribution Family Controls capability and all the extensions had the Development Family Controls capability. However, this caused provisioning issues when I tried to create a test flight build. I then removed the development capabilities from the extensions, and now everything works fine except oddly the Labels in the DeviceActivityReport no longer show anything. They worked fine before, and the same label logic is working 100% fine inside my main app. Anyone encounter this before?
1
0
240
Mar ’25
Ornament buttons broken by hoverEffect clipShape
TLDR: Applying a clipShape in a hoverEffect closure is preventing taps from getting through to buttons nested within an ornament. I need to make a custom ornament menu, similar to the stock ornament available via TabView but with some visual tweaks. It displays icons, and then expands to display a label as the user hovers. Example: I've put together a piece of sample code, following guidance from WWDC docs: VStack { } .ornament(attachmentAnchor: .scene(.leading)) { VStack { ForEach(0...7, id:\.self) { index in Button(action: { print(index) // <---- This will not print }) { HStack { Text("\(index)") Text(" button") } } } } .padding(12) .glassBackgroundEffect() .hoverEffect { effect, isActive, proxy in effect .clipShape(RoundedRectangle(cornerRadius: 36) .size(width: isActive ? proxy.size.width : 72, height: proxy.size.height, anchor: .leading) ) } } } The buttons in this code cannot be interacted with, as the print statement never executes. What am I missing here? I've managed to get some weird behavior, sometimes a specific clipShape (like a circle) will allow a tap on a single button, but not others.
1
0
147
Mar ’25
Unable to start a live activity
I'm unable to get live activity to show up in my app so I started to play with the demo app Emoji Rangers. The demo project initially only created a live activity in-app and then you're able to update it via the demo buttons. I added the following code to have it be able to start a live activity from the backend: func observePushToStartToken() { Task { for await data in Activity.pushToStartTokenUpdates { let token = data.map {String(format: "%02x", $0)}.joined() // Send token to the server print("got PUSHTOSTART TOKEN: (token)") } } } I get the token and then I use it to send this payload that should start the activity: { "aps":{ "timestamp":1743719911, "event":"start", "content-state":{ "currentHealthLevel":100, "eventDescription":"Adventure has begun!", "supercharged":true }, "input-push-token":1, "attributes-type":"AdventureAttributes", "attributes":{ "currentHealthLevel":100, "eventDescription":"Adventure has begun!", "supercharged":true }, "alert":{ "title":{ "loc-key":"%@ is on an adventure!", "loc-args":[ "Power Panda" ] }, "body":{ "loc-key":"%@ found a sword!", "loc-args":[ "Power Panda" ] }, "sound":"chime.aiff" } } } But unfortunately I get an error when I send it: [AdventureAttributes] Error creating activity: NSCocoaErrorDomain (4865) The data couldn't be read because it is missing. First step is to get this working, so I want to get your help in figuring out what I'm missing.
1
0
73
Apr ’25
CarPlay Question
Why is there no option as a CarPlay developer to enable the creation of an App to track and enter your car's maintenance records? I know the pat reply would be Apple doesn't want you to do this while car is in motion. But I would normally do this while parked at the dealership or other service provider no?
1
0
301
Mar ’25
Button Behavior between fullScreenCover and sheet
The behavior of the Button in ScrollView differs depending on how the View is displayed modally. When the View is displayed as a .fullScreenCover, if the button is touched and scrolled without releasing the finger, the touch event is canceled and the action of the Button is not called. On the other hand, if the View is displayed as a .sheet, the touch event is not canceled even if the view is scrolled without lifting the finger, and the action is called when the finger is released. In order to prevent accidental interaction, I feel that the behavior of .fullScreenCover is better, as it cancels the event immediately when scrolling. Can I change the behavior of .sheet? Demo movie is here: https://x.com/kenmaz/status/1896498312737611891 Sample code import SwiftUI @main struct SampleApp: App { var body: some Scene { WindowGroup { ContentView() } } } struct ContentView: View { @State private var showSheet = false @State private var showFullScreen = false var body: some View { VStack(spacing: 16) { Button("Sheet") { showSheet.toggle() } Button("Full screen") { showFullScreen.toggle() } } .sheet(isPresented: $showSheet) { SecondView() } .fullScreenCover(isPresented: $showFullScreen) { SecondView() } .font(.title) } } struct SecondView: View { @Environment(\.dismiss) var dismiss var body: some View { ScrollView { Button("Dismiss") { dismiss() } .buttonStyle(MyButtonStyle()) .padding(.top, 128) .font(.title) } } } private struct MyButtonStyle: ButtonStyle { func makeBody(configuration: Self.Configuration) -> some View { configuration .label .foregroundStyle(.red) .background(configuration.isPressed ? .gray : .clear) } }
Topic: UI Frameworks SubTopic: SwiftUI
0
0
190
Mar ’25