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

Requesting user Permission for Speech Framework crashes visionOS simulator
When a new application runs on VisionOS 2.4 simulator and tries to access the Speech Framework, prompting a request for authorisation to use Speech Recognition, the application freezes. Using Swift 6. Report Identifier: FB17666252 @MainActor func checkAvailabilityAndPermissions() async { logger.debug("Checking speech recognition availability and permissions...") // 1. Verify that the speechRecognizer instance exists guard let recognizer = speechRecognizer else { logger.error("Speech recognizer is nil - speech recognition won't be available.") reportError(.configurationError(description: "Speech recognizer could not be created."), context: "checkAvailabilityAndPermissions") self.isAvailable = false return } // 2. Check recognizer availability (might change at runtime) if !recognizer.isAvailable { logger.error("Speech recognizer is not available for the current locale.") reportError(.configurationError(description: "Speech recognizer not available."), context: "checkAvailabilityAndPermissions") self.isAvailable = false return } logger.trace("Speech recognizer exists and is available.") // 3. Request Speech Recognition Authorization // IMPORTANT: Add `NSSpeechRecognitionUsageDescription` to Info.plist let speechAuthStatus = SFSpeechRecognizer.authorizationStatus() // FAILS HERE logger.debug("Current Speech Recognition authorization status: \(speechAuthStatus.rawValue)") if speechAuthStatus == .notDetermined { logger.info("Requesting speech recognition authorization...") // Use structured concurrency to wait for permission result let authStatus = await withCheckedContinuation { continuation in SFSpeechRecognizer.requestAuthorization { status in continuation.resume(returning: status) } } logger.debug("Received authorization status: \(authStatus.rawValue)") // Now handle the authorization result let speechAuthorized = (authStatus == .authorized) handleAuthorizationStatus(status: authStatus, type: "Speech Recognition") // If speech is granted, now check microphone if speechAuthorized { await checkMicrophonePermission() } } else { let speechAuthorized = (speechAuthStatus == .authorized) handleAuthorizationStatus(status: speechAuthStatus, type: "Speech Recognition") // If speech is already authorized, check microphone if speechAuthorized { await checkMicrophonePermission() } } }
1
0
176
May ’25
SwiftUI List DisclosureGroup Rendering Issues on macOS 13 & 14
Issue Description Whenever the first item in the List is a DisclosureGroup, all subsequent disclosure groups work fine. However, if the first item is not a disclosure group, the disclosure groups in subsequent items do not render correctly. This issue does not occur in macOS 15, where everything works as expected. Has anyone else encountered this behavior, or does anyone have a workaround for macOS 13 & 14? I’m not using OutlineGroup because I need to bind to an isExpanded property for each row in the list. Reproduction Steps I’ve created a small test project to illustrate the issue: Press “Insert item at top” to add a non-disclosure item at the start of the list. Then, press “Append item with sub-item” to add a disclosure group further down. The disclosure group does not display correctly. The label of the disclosure group renders fine, but the content of the disclosure group does not display at all. Press "Insert item at top with sub-item" and the list displays as expected. Build Environment macOS 15.3.2 (24D81) Xcode Version 16.2 (16C5032a) Issue Observed macOS 13 & 14 (bug occurs) macOS 15 (works correctly) Sample Code import SwiftUI class ListItem: ObservableObject, Hashable, Identifiable { var id = UUID() @Published var name: String @Published var subItems: [ListItem]? @Published var isExpanded: Bool = true init( name: String, subjobs: [ListItem]? = nil ) { self.name = name self.subItems = subjobs } static func == (lhs: ListItem, rhs: ListItem) -> Bool { lhs.id == rhs.id } func hash(into hasher: inout Hasher) { hasher.combine(id) } } struct ContentView: View { @State private var listItems: [ListItem] = [] @State private var selectedJob: ListItem? @State private var redraw: Int = 0 var body: some View { VStack { List(selection: $selectedJob) { ForEach(self.listItems, id: \.id) { job in self.itemRowView(for: job) } } .id(redraw) Button("Insert item at top") { self.listItems.insert( ListItem( name: "List item \(listItems.count)" ), at: 0 ) } Button("Insert item at top with sub-item") { self.listItems.insert( ListItem( name: "List item \(listItems.count)", subjobs: [ListItem(name: "Sub-item")] ), at: 0 ) } Button("Append item") { self.listItems.append( ListItem( name: "List item \(listItems.count)" ) ) } Button("Append item with sub-item") { self.listItems.append( ListItem( name: "List item \(listItems.count)", subjobs: [ListItem(name: "Sub-item")] ) ) } Button("Clear") { self.listItems.removeAll() } Button("Redraw") { self.redraw += 1 } } } @ViewBuilder private func itemRowView(for job: ListItem) -> some View { if job.subItems == nil { self.itemLabelView(for: job) } else { AnyView( erasing: ListItemDisclosureGroup(job: job) { self.itemLabelView(for: job) } jobRowView: { child in self.itemRowView(for: child) } ) } } @ViewBuilder private func itemLabelView(for job: ListItem) -> some View { Text(job.name) } struct ListItemDisclosureGroup<LabelView: View, RowView: View>: View { @ObservedObject var job: ListItem @ViewBuilder let labelView: () -> LabelView @ViewBuilder let jobRowView: (ListItem) -> RowView var body: some View { DisclosureGroup(isExpanded: $job.isExpanded) { if let children = job.subItems { ForEach(children, id: \.id) { child in self.jobRowView(child) } } } label: { self.labelView() } } } }
1
0
78
Mar ’25
Buttons in menu don't respect the environment value of .layoutDirection in SwiftUI
Problem Setting ".environment(.layoutDirection, .rightToLeft)" to a view programmatically won't make buttons in menu to show right to left. However, setting ".environment(.locale, .init(identifier: "he-IL"))" to a view programmatically makes buttons in menu to show Hebrew strings correctly. Development environment: Xcode 16.x, macOS 15.3.1 Target iOS: iOS 17 - iOS 18 The expected result is that the button in the menu should be displayed as an icon then a text from left to right. Code to demonstrate the problem: struct ContentView: View { var body: some View { VStack(alignment: .leading) { Text("Buttons in menu don't respect the environment value of .layoutDirection") .font(.subheadline) .padding(.bottom, 48) /// This button respects both "he-IL" of ".locale" and ".rightToLeft" of ".layoutDirection". Button { print("Button tapped") } label: { HStack { Text("Send") Image(systemName: "paperplane") } } Menu { /// This button respects "he-IL" of ".locale" but doesn't respect ".rightToLeft" of ".layoutDirection". Button { print("Button tapped") } label: { HStack { Text("Send") Image(systemName: "paperplane") } } } label: { Text("Menu") } } .padding() .environment(\.locale, .init(identifier: "he-IL")) .environment(\.layoutDirection, .rightToLeft) } }
4
0
94
Mar ’25
Strange media player overlay main screen
Respected Madam/Sir, The following code works well in the past year, but when I test it again on my iPhone which run iOS 16.7.8, a strange media player appeared and overlay the main screen of my app, I really don't know what happened there, I'm struggling to resolve it hours, but it still always appear, help please! Any suggestion, direction, api misused, would be appreciated. let mainScreenController : ViewController = ViewController() self.window = UIWindow(frame: UIScreen.main.bounds) self.window?.rootViewController = mainScreenController self.window?.makeKeyAndVisible()
Topic: UI Frameworks SubTopic: UIKit
2
0
122
Apr ’25
Unexpected UINavigationBar Behavior During View Transitions in iOS 18
In iOS 18, I've observed unexpected behavior related to the UINavigationBar when transitioning between view controllers that have differing navigation bar visibility settings. Specifically, when returning from a modal presentation or a web view, the navigation bar reappears with an unexpected height (e.g., 103 points) and lacks content, displaying only an empty bar. Start with a UIViewController (e.g., HomeViewController) where the navigation bar is hidden using: override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) navigationController?.setNavigationBarHidden(true, animated: animated) } Present another UIViewController (e.g., a web view) modally. Dismiss the presented view controller. Observe that upon returning to HomeViewController, the navigation bar is visible with increased height and lacks expected content. Expected Behavior: The navigation bar should remain hidden upon returning to HomeViewController, maintaining the state it had prior to presenting the modal view controller. Actual Behavior: Upon dismissing the modal view controller, the navigation bar becomes visible with an unexpected height and lacks content, leading to a disrupted user interface. Additional Observations: This issue is specific to iOS 18; it does not occur in iOS 17 or earlier versions. The problem seems to stem from setting the navigation bar to be visible in the viewWillDisappear method, as shown below: override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) navigationController?.setNavigationBarHidden(false, animated: animated) } Removing or modifying this line mitigates the issue, suggesting a change in the view controller lifecycle behavior in iOS 18. Request for Clarification: Is this change in behavior intentional in iOS 18, or is it a regression? Understanding whether this is a new standard or a bug will help in implementing appropriate solutions. Workaround: As a temporary measure, I've adjusted the navigation bar visibility settings to avoid changing its state in viewWillDisappear, instead managing it in viewWillAppear or viewDidAppear. References: Similar issues have been discussed in the Apple Developer Forums: iPad OS 18 UINavigationBar display incorrectly
Topic: UI Frameworks SubTopic: UIKit
0
0
116
May ’25
Animated scale effect causes NSCursor to reset in SwiftUI macOS app
For my macOS app, I'm trying to change the mouse cursor to a pointing hand while hovering over a specific view. However, when the view is scaled with an animation triggered by hovering (using .scaleEffect() and .animation()), the cursor doesn't change as expected. Is there any workaround to fix this? This is a sample code: struct ContentView: View { @State private var hovering = false var body: some View { VStack { Text("Hover me") .padding() .background(hovering ? Color.blue : Color.gray) .scaleEffect(hovering ? 1.2 : 1.0) .animation(.linear(duration: 0.2), value: hovering) .onHover { hovering in self.hovering = hovering if hovering { NSCursor.pointingHand.push() } else { NSCursor.pop() } } } .frame(width: 200, height: 200) } } This is how it works: As you can see, when the pointer enters the view, the cursor changes momentarily before reverting back to the arrow icon. I also tried using NSTrackingArea with an NSView placed over the view, but it did not solve the issue. It might be that the combination of .scaleEffect() and .animation() is causing a forced cursor reset (possibly related to the use of NSWindow.disableCursorRects() or something similar). However, I'm not entirely sure. Any insights or suggestions would be greatly appreciated. Thanks!
2
0
136
Apr ’25
NavigationStack inside NavigationSplitView broken animation
In tvOS when using NavigationStack inside NavigationSplitView as below: @State private var selectedItem: String? @State private var navigationPath = NavigationPath() // Track navigation state manually var body: some View { NavigationSplitView { List(selection: $selectedItem) { Button("Item 1") { selectedItem = "Detail View 1" } Button("Item 2") { selectedItem = "Detail View 2" } } } detail: { NavigationStack(path: $navigationPath) { DetailView() .navigationDestination(for: String.self) { value in Text("New Screen: \(value)") } } } } } This example completely breaks the animation inside NavigationStack while navigating between different views, using withAnimation also breaks the navigation as the old view seems to be still in stack and is shown in the new view background. I have also submitted bug report: https://feedbackassistant.apple.com/feedback/16933927
2
0
141
Mar ’25
Animate layout change
I want to show a view, where the user can add or remove items shown as icons, which are sorted in two groups: squares and circles. When there are only squares, they should be shown in one row: [] [] [] When there are so many squares that they don’t fit horizontally, a (horizontal) scrollview will be used, with scroll-indicator always shown to indicate that not all squares are visible. When there are only circles, they also should be shown in one row: () () () When there are so many circles that they don’t fit horizontally, a (horizontal) scrollview will be used, with scroll-indicator always shown to indicate that not all circles are visible. When there a few squares and a few circles, they should be shown adjacent in one row: [] [] () () When there are so many squares and circles that they don’t fit horizontally, they should be shown in two rows, squares on top, circles below: [] [] [] () () () When there are either too many squares or too many circles (or both) to fit horizontally, one common (horizontal) scrollview will be used, with scroll-indicator always shown to indicate that not all items are visible. I started with ViewThatFits: (see first code block) { let squares = HStack { ForEach(model.squares, id: \.self) { square in Image(square) } } let circles = HStack { ForEach(model.circles, id: \.self) { circle in Image(circle) } } let oneLine = HStack { squares circles } let twoLines = VStack { squares circles } let scrollView = ScrollView(.horizontal) { twoLines }.scrollIndicators(.visible) ViewThatFits(in: .horizontal) { oneLine twoLines scrollView.clipped() } } While this works in general, it doesn’t animate properly. When the user adds or removes an image the model gets updated, (see second code block) withAnimation(Animation.easeIn(duration: 0.25)) { model.squares += image } and the view animates with the existing images either making space for a new appearing square/circle, or moving together to close the gap where an image disappeared. This works fine as long as ViewThatFits returns the same view. However, when adding 1 image leads to ViewThatFits switching from oneLine to twoLines, this switch is not animated. The circles jump to the new position under the squares, instead of sliding there. I searched online for a solution, but this seems to be a known problem of ViewThatFits. It doesn't animate when it switches... (tbc)
1
0
125
Mar ’25
how to get subviews of a SwiftUI view in UIKit environment
I have a SwiftUI view that I have wrapped using UIHostingController for use within UIKit. Requirement: Within the UIKit environment, I want to get all the subviews of this SwiftUI view and determine whether the images within those subviews have finished loading. For UIKit views, we can use view.subviews to get all the subviews and do the check. However, for SwiftUI views, I found that the view.subviews turns out to be an empty array, making it impossible to do further checks. So the question is How can I get the subviews of a SwiftUI view?
2
0
128
May ’25
Live Activity resets to initial state after 8+ hours in background
Hi Apple team and community, We’re encountering a strange issue with Live Activity that seems related to memory management or background lifecycle. ❓ Issue: Our app updates a Live Activity regularly (every 3 minutes) using .update(...). However, after the app remains in the background for around 8 hours, the Live Activity reverts to the initial state that was passed into .request(...). Even though the app continues sending updates in the background, the UI on the Lock Screen and Dynamic Island resets to the original state.
0
0
76
Apr ’25
Mac Catalyst SplitViewController, UITitlebar bugs?
Bringing my iPad app to Mac Catalyst as iPad idiom. Primary interface is a UISplitViewController. Two things I think are bugs unless someone replies with a fix. SplitViewController is setup in two column with left column as sidebar: split.setViewController(primary, for: .primary) split.setViewController(secondary, for: .secondary) split.preferredDisplayMode = .oneBesideSecondary split.preferredSplitBehavior = .tile split.presentsWithGesture = true #if targetEnvironment(macCatalyst) split.primaryBackgroundStyle = .sidebar split.displayModeButtonVisibility = .never #endif The displayMode button aligns vertically with the navigation bar and below the 3 window control buttons (close, minimize, full screen), whereas on other macOS apps using SplitViewController such as Apple Notes app, the displayMode button aligns vertically and just to the right of the the 3 window control buttons (close, minimize, full screen). I downloaded the Apple Example app called Menus that is supposed to be a prime example of a Mac Catalyst app, and I see author must have faced the same bug and instead created their own displayMode button and placed it on the UITitlebar's toolBar. In my secondary ViewController which is a subclass of a UITableViewController, tapping a row, calls show and in a SplitViewController, that pushes another detailVC onto the Nav stack as expected. The UIWindowScene's UITitlebar which appears over the top of the secondary VC looks correct. This detailVC is a subclass of a UITableViewController. Finally, tapping a row in the table of the detailVC calls show but this time, the ViewController is actually a UIHostingViewController wrapping a SwiftUI View. At this point the UIWindowScene's UITitlebar changes appearance and takes on the same lightened color similar to the sidebar (primary) appearance. With UITitlebarTitleVisibility set to hidden and if I set the titlebar.toolbar to nil, (which removes the UITitlebar, there is no appearance issue. Running on iPad, with no UITitlebar, there is no odd lightening experienced when the UIHostingController is shown. I think this has something to do with the UIHostingController within Mac Catalyst.
1
0
176
May ’25
App Name Display
For now, my app name length is more than 20 characters, so the iPhone app name displays without a space, and uses the range operator to ensure showing the rest in the next line. Is it possible to show space and name with 2 lines?
Topic: UI Frameworks SubTopic: General Tags:
0
0
80
May ’25
Recently used applications on guardian phone - FamilyControls, DeviceActivityReport
For an iOS app that runs in both child and parent mode across iOS devices. On the child device, with Family Controls enabled using .child permissions via AuthorizationCenter.requestAuthorization(for: .child). Is any way to display a list of recently used apps by the child on the parent (guardian) device, in a privacy-preserving and Apple-compliant way?
1
0
146
May ’25
SwiftUI macOS simple NavigationStack and NavigationLink -> problem on multiplatform project
I had a problem with my app (or in my setup) and searching the web I found a very simple code where part of my problem occurs. I create a new Multiplatform App and paste this code in ContentView. import SwiftUI struct ContentView: View { var body: some View { NavigationStack { VStack { Text("Navigation article") .font(.title) .padding() NavigationLink("Go to the second view", destination: SecondView()) .padding() } .navigationTitle("First View") } } } struct SecondView: View { var body: some View { Text("This is the Second view") .font(.headline) .padding() .navigationTitle("Second View") } } run on iPhone/ iOS no problem run on a Mac/macOS Going from view 1 to view 2 work, the back arrow on view 2 is there, and it is working but the second time I go to the view 2, the back arrow is gone. after looking closely I can see the Arrow Underneath the S of SecondView. I have tried many things and could not make it work. I post this in a HackingWithSwift forum and somebody tried the code and said it work. so it seems the problem could be related to my setup but I create another user in my computer , same problem and tried it on my another computer, same problem.
Topic: UI Frameworks SubTopic: SwiftUI
7
0
93
Apr ’25
iOS app crash with UIKitcore - UIAlertController
I have recently submitted a new app version to the Appstore with Xcode 15.0. Unfortunately, I have started to see the below crash in the Xcode organiser &gt; Crashes section occurring for more number of times. UIKitCore: +[UIAlertController _alertControllerContainedInViewController:] + 160 The exception trace is not leading to main() function but not pointing to any of the code line. I had used UIAlertController in the past versions to show the alerts but there is no code written in the current version code related to UIAlertController. Only from the latest version, this kind of crash started to surface. In the latest release, We have added a third party SDK and while implementing the SDK, we had added the Location and Bluetooth Permissions in Info.plist file. But as we don't want to use/track the Location and Bluetooth details from the app, the SDK team has disabled the Location and Bluetooth settings to not reflect in the tracked data. Is this behaviour creating any conflict with the UIAlertController and logging the crash? Because by default the OS tries to show the alert when the permissions exist in the plist file, but the alert will not come as the service is disabled on the SDK server settings. Is this creating any conflict and logging the crash. Please extend your help.
3
0
881
May ’25
How to prevent iOS VoiceOver from speaking accessibility-labels and traits?
I have a button with the following properties: accessibilityLabel: "Action Button", traits: "Button", accessibilityHint: "Performs the main action". The voiceover reads the button as follows: Action Button, Button, Performs the main action. I want to understand how to configure it to only speak the accessibilityHint or only the accessibilityLabel and never speak the traits. In another example, a switch has the traits: Button, and Toggle. So these traits are a part of what the voiceover speaks. I want only the accessibilityLabel or accessibilityHint to be spoken in this case. Please let me know how. Thanks
1
0
132
May ’25
How to programmatically set cursor position of a text field in SwiftUI
I would like to understand how to programmatically set the position of a cursor in a SwiftUI TextField. In UIKit this can be done using the selectedTextRange property, but I couldn't find a similar way to achieve this with pure SwiftUI. I want to figure out something like setCursorPosition (index:) - maybe by tracking the position in a @State or any other way. I understand that I can do this using UIViewRepresentable but I am looking for a pure SwiftUI solution and wanted to know if there is any.
2
0
463
Mar ’25
RePlayKit:screen recording method return sampleBuffer is nil
I want record screen in my app,the method startCaptureWithHandler:completionHandler:,the sampleBuffer, It is supposed to exist but it has become nil.Not only that,but there‘s another problem,when I want to stop recording and save the video,I will check [RPScreenRecorder sharedRecorder].recording first, it will be false sometime,that problems are unusual in iOS 18.3.2 iPhoneXs Max,and unexpected,here is my code -(void)startCaptureScreen { NSLog(@"AKA++ startCaptureScreen"); if ([[RPScreenRecorder sharedRecorder] isRecording]) { return; } //屏幕录制 [[RPScreenRecorder sharedRecorder]setMicrophoneEnabled:YES]; NSLog(@"AKA++ MicrophoneEnabled AAAA startCaptureScreen"); [[RPScreenRecorder sharedRecorder]setCameraEnabled:YES]; [[RPScreenRecorder sharedRecorder] startCaptureWithHandler:^(CMSampleBufferRef _Nonnull sampleBuffer, RPSampleBufferType bufferType, NSError * _Nullable error) { if(self.assetWriter == nil){ if (self.AVAssetWriterStatus == 0) { [self setupAssetWriterAndStartWith:sampleBuffer]; } } if (self.AVAssetWriterStatus != 2) { return; } if (error) { // deal with error return; } if (self.assetWriter.status != AVAssetWriterStatusWriting) { [self assetWriterAppendSampleBufferFailWith:bufferType]; return; } if (bufferType == RPSampleBufferTypeVideo) { if(self.assetWriter.status == 0 ||self.assetWriter.status > 2){ } else if(self.videoAssetWriterInput.readyForMoreMediaData == YES){ BOOL success = [self.videoAssetWriterInput appendSampleBuffer:sampleBuffer]; } } if (bufferType == RPSampleBufferTypeAudioMic) { if(self.assetWriter.status == 0 ||self.assetWriter.status > 2){ } else if(self.audioAssetWriterInput.readyForMoreMediaData == YES){ BOOL success = [self.audioAssetWriterInput appendSampleBuffer:sampleBuffer]; } } } completionHandler:^(NSError * _Nullable error) { //deal with error }]; } and than ,when want to save it : -(void)stopRecording { if([[RPScreenRecorder sharedRecorder] isRecording]){ // The problem is sporadic,recording action failed,it makes me confused } [[RPScreenRecorder sharedRecorder] stopCaptureWithHandler:^(NSError * _Nullable error) { if(!error) { //post message } }]; }
0
0
91
Apr ’25
drag a modelEntity inside an Immersive space and track position
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 RealityKit import RealityKitContent import Foundation @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<Float>? = 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() .targetedToEntity(sphere) .onChanged { _ in self.isDragging = true } .onEnded { _ in self.isDragging = false } } var body: some View { Text("Hello, World!") RealityView { content in //1. Anchor Entity let anchor = AnchorEntity(world: SIMD3<Float>(0, 0, -1)) let ball = sphere //1.2 add component to ball ball.components.set(InputTargetComponent()) //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) } }
0
0
69
Apr ’25
Requesting user Permission for Speech Framework crashes visionOS simulator
When a new application runs on VisionOS 2.4 simulator and tries to access the Speech Framework, prompting a request for authorisation to use Speech Recognition, the application freezes. Using Swift 6. Report Identifier: FB17666252 @MainActor func checkAvailabilityAndPermissions() async { logger.debug("Checking speech recognition availability and permissions...") // 1. Verify that the speechRecognizer instance exists guard let recognizer = speechRecognizer else { logger.error("Speech recognizer is nil - speech recognition won't be available.") reportError(.configurationError(description: "Speech recognizer could not be created."), context: "checkAvailabilityAndPermissions") self.isAvailable = false return } // 2. Check recognizer availability (might change at runtime) if !recognizer.isAvailable { logger.error("Speech recognizer is not available for the current locale.") reportError(.configurationError(description: "Speech recognizer not available."), context: "checkAvailabilityAndPermissions") self.isAvailable = false return } logger.trace("Speech recognizer exists and is available.") // 3. Request Speech Recognition Authorization // IMPORTANT: Add `NSSpeechRecognitionUsageDescription` to Info.plist let speechAuthStatus = SFSpeechRecognizer.authorizationStatus() // FAILS HERE logger.debug("Current Speech Recognition authorization status: \(speechAuthStatus.rawValue)") if speechAuthStatus == .notDetermined { logger.info("Requesting speech recognition authorization...") // Use structured concurrency to wait for permission result let authStatus = await withCheckedContinuation { continuation in SFSpeechRecognizer.requestAuthorization { status in continuation.resume(returning: status) } } logger.debug("Received authorization status: \(authStatus.rawValue)") // Now handle the authorization result let speechAuthorized = (authStatus == .authorized) handleAuthorizationStatus(status: authStatus, type: "Speech Recognition") // If speech is granted, now check microphone if speechAuthorized { await checkMicrophonePermission() } } else { let speechAuthorized = (speechAuthStatus == .authorized) handleAuthorizationStatus(status: speechAuthStatus, type: "Speech Recognition") // If speech is already authorized, check microphone if speechAuthorized { await checkMicrophonePermission() } } }
Replies
1
Boosts
0
Views
176
Activity
May ’25
SwiftUI List DisclosureGroup Rendering Issues on macOS 13 & 14
Issue Description Whenever the first item in the List is a DisclosureGroup, all subsequent disclosure groups work fine. However, if the first item is not a disclosure group, the disclosure groups in subsequent items do not render correctly. This issue does not occur in macOS 15, where everything works as expected. Has anyone else encountered this behavior, or does anyone have a workaround for macOS 13 & 14? I’m not using OutlineGroup because I need to bind to an isExpanded property for each row in the list. Reproduction Steps I’ve created a small test project to illustrate the issue: Press “Insert item at top” to add a non-disclosure item at the start of the list. Then, press “Append item with sub-item” to add a disclosure group further down. The disclosure group does not display correctly. The label of the disclosure group renders fine, but the content of the disclosure group does not display at all. Press "Insert item at top with sub-item" and the list displays as expected. Build Environment macOS 15.3.2 (24D81) Xcode Version 16.2 (16C5032a) Issue Observed macOS 13 & 14 (bug occurs) macOS 15 (works correctly) Sample Code import SwiftUI class ListItem: ObservableObject, Hashable, Identifiable { var id = UUID() @Published var name: String @Published var subItems: [ListItem]? @Published var isExpanded: Bool = true init( name: String, subjobs: [ListItem]? = nil ) { self.name = name self.subItems = subjobs } static func == (lhs: ListItem, rhs: ListItem) -> Bool { lhs.id == rhs.id } func hash(into hasher: inout Hasher) { hasher.combine(id) } } struct ContentView: View { @State private var listItems: [ListItem] = [] @State private var selectedJob: ListItem? @State private var redraw: Int = 0 var body: some View { VStack { List(selection: $selectedJob) { ForEach(self.listItems, id: \.id) { job in self.itemRowView(for: job) } } .id(redraw) Button("Insert item at top") { self.listItems.insert( ListItem( name: "List item \(listItems.count)" ), at: 0 ) } Button("Insert item at top with sub-item") { self.listItems.insert( ListItem( name: "List item \(listItems.count)", subjobs: [ListItem(name: "Sub-item")] ), at: 0 ) } Button("Append item") { self.listItems.append( ListItem( name: "List item \(listItems.count)" ) ) } Button("Append item with sub-item") { self.listItems.append( ListItem( name: "List item \(listItems.count)", subjobs: [ListItem(name: "Sub-item")] ) ) } Button("Clear") { self.listItems.removeAll() } Button("Redraw") { self.redraw += 1 } } } @ViewBuilder private func itemRowView(for job: ListItem) -> some View { if job.subItems == nil { self.itemLabelView(for: job) } else { AnyView( erasing: ListItemDisclosureGroup(job: job) { self.itemLabelView(for: job) } jobRowView: { child in self.itemRowView(for: child) } ) } } @ViewBuilder private func itemLabelView(for job: ListItem) -> some View { Text(job.name) } struct ListItemDisclosureGroup<LabelView: View, RowView: View>: View { @ObservedObject var job: ListItem @ViewBuilder let labelView: () -> LabelView @ViewBuilder let jobRowView: (ListItem) -> RowView var body: some View { DisclosureGroup(isExpanded: $job.isExpanded) { if let children = job.subItems { ForEach(children, id: \.id) { child in self.jobRowView(child) } } } label: { self.labelView() } } } }
Replies
1
Boosts
0
Views
78
Activity
Mar ’25
Buttons in menu don't respect the environment value of .layoutDirection in SwiftUI
Problem Setting ".environment(.layoutDirection, .rightToLeft)" to a view programmatically won't make buttons in menu to show right to left. However, setting ".environment(.locale, .init(identifier: "he-IL"))" to a view programmatically makes buttons in menu to show Hebrew strings correctly. Development environment: Xcode 16.x, macOS 15.3.1 Target iOS: iOS 17 - iOS 18 The expected result is that the button in the menu should be displayed as an icon then a text from left to right. Code to demonstrate the problem: struct ContentView: View { var body: some View { VStack(alignment: .leading) { Text("Buttons in menu don't respect the environment value of .layoutDirection") .font(.subheadline) .padding(.bottom, 48) /// This button respects both "he-IL" of ".locale" and ".rightToLeft" of ".layoutDirection". Button { print("Button tapped") } label: { HStack { Text("Send") Image(systemName: "paperplane") } } Menu { /// This button respects "he-IL" of ".locale" but doesn't respect ".rightToLeft" of ".layoutDirection". Button { print("Button tapped") } label: { HStack { Text("Send") Image(systemName: "paperplane") } } } label: { Text("Menu") } } .padding() .environment(\.locale, .init(identifier: "he-IL")) .environment(\.layoutDirection, .rightToLeft) } }
Replies
4
Boosts
0
Views
94
Activity
Mar ’25
Strange media player overlay main screen
Respected Madam/Sir, The following code works well in the past year, but when I test it again on my iPhone which run iOS 16.7.8, a strange media player appeared and overlay the main screen of my app, I really don't know what happened there, I'm struggling to resolve it hours, but it still always appear, help please! Any suggestion, direction, api misused, would be appreciated. let mainScreenController : ViewController = ViewController() self.window = UIWindow(frame: UIScreen.main.bounds) self.window?.rootViewController = mainScreenController self.window?.makeKeyAndVisible()
Topic: UI Frameworks SubTopic: UIKit
Replies
2
Boosts
0
Views
122
Activity
Apr ’25
Unexpected UINavigationBar Behavior During View Transitions in iOS 18
In iOS 18, I've observed unexpected behavior related to the UINavigationBar when transitioning between view controllers that have differing navigation bar visibility settings. Specifically, when returning from a modal presentation or a web view, the navigation bar reappears with an unexpected height (e.g., 103 points) and lacks content, displaying only an empty bar. Start with a UIViewController (e.g., HomeViewController) where the navigation bar is hidden using: override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) navigationController?.setNavigationBarHidden(true, animated: animated) } Present another UIViewController (e.g., a web view) modally. Dismiss the presented view controller. Observe that upon returning to HomeViewController, the navigation bar is visible with increased height and lacks expected content. Expected Behavior: The navigation bar should remain hidden upon returning to HomeViewController, maintaining the state it had prior to presenting the modal view controller. Actual Behavior: Upon dismissing the modal view controller, the navigation bar becomes visible with an unexpected height and lacks content, leading to a disrupted user interface. Additional Observations: This issue is specific to iOS 18; it does not occur in iOS 17 or earlier versions. The problem seems to stem from setting the navigation bar to be visible in the viewWillDisappear method, as shown below: override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) navigationController?.setNavigationBarHidden(false, animated: animated) } Removing or modifying this line mitigates the issue, suggesting a change in the view controller lifecycle behavior in iOS 18. Request for Clarification: Is this change in behavior intentional in iOS 18, or is it a regression? Understanding whether this is a new standard or a bug will help in implementing appropriate solutions. Workaround: As a temporary measure, I've adjusted the navigation bar visibility settings to avoid changing its state in viewWillDisappear, instead managing it in viewWillAppear or viewDidAppear. References: Similar issues have been discussed in the Apple Developer Forums: iPad OS 18 UINavigationBar display incorrectly
Topic: UI Frameworks SubTopic: UIKit
Replies
0
Boosts
0
Views
116
Activity
May ’25
Animated scale effect causes NSCursor to reset in SwiftUI macOS app
For my macOS app, I'm trying to change the mouse cursor to a pointing hand while hovering over a specific view. However, when the view is scaled with an animation triggered by hovering (using .scaleEffect() and .animation()), the cursor doesn't change as expected. Is there any workaround to fix this? This is a sample code: struct ContentView: View { @State private var hovering = false var body: some View { VStack { Text("Hover me") .padding() .background(hovering ? Color.blue : Color.gray) .scaleEffect(hovering ? 1.2 : 1.0) .animation(.linear(duration: 0.2), value: hovering) .onHover { hovering in self.hovering = hovering if hovering { NSCursor.pointingHand.push() } else { NSCursor.pop() } } } .frame(width: 200, height: 200) } } This is how it works: As you can see, when the pointer enters the view, the cursor changes momentarily before reverting back to the arrow icon. I also tried using NSTrackingArea with an NSView placed over the view, but it did not solve the issue. It might be that the combination of .scaleEffect() and .animation() is causing a forced cursor reset (possibly related to the use of NSWindow.disableCursorRects() or something similar). However, I'm not entirely sure. Any insights or suggestions would be greatly appreciated. Thanks!
Replies
2
Boosts
0
Views
136
Activity
Apr ’25
NavigationStack inside NavigationSplitView broken animation
In tvOS when using NavigationStack inside NavigationSplitView as below: @State private var selectedItem: String? @State private var navigationPath = NavigationPath() // Track navigation state manually var body: some View { NavigationSplitView { List(selection: $selectedItem) { Button("Item 1") { selectedItem = "Detail View 1" } Button("Item 2") { selectedItem = "Detail View 2" } } } detail: { NavigationStack(path: $navigationPath) { DetailView() .navigationDestination(for: String.self) { value in Text("New Screen: \(value)") } } } } } This example completely breaks the animation inside NavigationStack while navigating between different views, using withAnimation also breaks the navigation as the old view seems to be still in stack and is shown in the new view background. I have also submitted bug report: https://feedbackassistant.apple.com/feedback/16933927
Replies
2
Boosts
0
Views
141
Activity
Mar ’25
Animate layout change
I want to show a view, where the user can add or remove items shown as icons, which are sorted in two groups: squares and circles. When there are only squares, they should be shown in one row: [] [] [] When there are so many squares that they don’t fit horizontally, a (horizontal) scrollview will be used, with scroll-indicator always shown to indicate that not all squares are visible. When there are only circles, they also should be shown in one row: () () () When there are so many circles that they don’t fit horizontally, a (horizontal) scrollview will be used, with scroll-indicator always shown to indicate that not all circles are visible. When there a few squares and a few circles, they should be shown adjacent in one row: [] [] () () When there are so many squares and circles that they don’t fit horizontally, they should be shown in two rows, squares on top, circles below: [] [] [] () () () When there are either too many squares or too many circles (or both) to fit horizontally, one common (horizontal) scrollview will be used, with scroll-indicator always shown to indicate that not all items are visible. I started with ViewThatFits: (see first code block) { let squares = HStack { ForEach(model.squares, id: \.self) { square in Image(square) } } let circles = HStack { ForEach(model.circles, id: \.self) { circle in Image(circle) } } let oneLine = HStack { squares circles } let twoLines = VStack { squares circles } let scrollView = ScrollView(.horizontal) { twoLines }.scrollIndicators(.visible) ViewThatFits(in: .horizontal) { oneLine twoLines scrollView.clipped() } } While this works in general, it doesn’t animate properly. When the user adds or removes an image the model gets updated, (see second code block) withAnimation(Animation.easeIn(duration: 0.25)) { model.squares += image } and the view animates with the existing images either making space for a new appearing square/circle, or moving together to close the gap where an image disappeared. This works fine as long as ViewThatFits returns the same view. However, when adding 1 image leads to ViewThatFits switching from oneLine to twoLines, this switch is not animated. The circles jump to the new position under the squares, instead of sliding there. I searched online for a solution, but this seems to be a known problem of ViewThatFits. It doesn't animate when it switches... (tbc)
Replies
1
Boosts
0
Views
125
Activity
Mar ’25
how to get subviews of a SwiftUI view in UIKit environment
I have a SwiftUI view that I have wrapped using UIHostingController for use within UIKit. Requirement: Within the UIKit environment, I want to get all the subviews of this SwiftUI view and determine whether the images within those subviews have finished loading. For UIKit views, we can use view.subviews to get all the subviews and do the check. However, for SwiftUI views, I found that the view.subviews turns out to be an empty array, making it impossible to do further checks. So the question is How can I get the subviews of a SwiftUI view?
Replies
2
Boosts
0
Views
128
Activity
May ’25
Live Activity resets to initial state after 8+ hours in background
Hi Apple team and community, We’re encountering a strange issue with Live Activity that seems related to memory management or background lifecycle. ❓ Issue: Our app updates a Live Activity regularly (every 3 minutes) using .update(...). However, after the app remains in the background for around 8 hours, the Live Activity reverts to the initial state that was passed into .request(...). Even though the app continues sending updates in the background, the UI on the Lock Screen and Dynamic Island resets to the original state.
Replies
0
Boosts
0
Views
76
Activity
Apr ’25
Mac Catalyst SplitViewController, UITitlebar bugs?
Bringing my iPad app to Mac Catalyst as iPad idiom. Primary interface is a UISplitViewController. Two things I think are bugs unless someone replies with a fix. SplitViewController is setup in two column with left column as sidebar: split.setViewController(primary, for: .primary) split.setViewController(secondary, for: .secondary) split.preferredDisplayMode = .oneBesideSecondary split.preferredSplitBehavior = .tile split.presentsWithGesture = true #if targetEnvironment(macCatalyst) split.primaryBackgroundStyle = .sidebar split.displayModeButtonVisibility = .never #endif The displayMode button aligns vertically with the navigation bar and below the 3 window control buttons (close, minimize, full screen), whereas on other macOS apps using SplitViewController such as Apple Notes app, the displayMode button aligns vertically and just to the right of the the 3 window control buttons (close, minimize, full screen). I downloaded the Apple Example app called Menus that is supposed to be a prime example of a Mac Catalyst app, and I see author must have faced the same bug and instead created their own displayMode button and placed it on the UITitlebar's toolBar. In my secondary ViewController which is a subclass of a UITableViewController, tapping a row, calls show and in a SplitViewController, that pushes another detailVC onto the Nav stack as expected. The UIWindowScene's UITitlebar which appears over the top of the secondary VC looks correct. This detailVC is a subclass of a UITableViewController. Finally, tapping a row in the table of the detailVC calls show but this time, the ViewController is actually a UIHostingViewController wrapping a SwiftUI View. At this point the UIWindowScene's UITitlebar changes appearance and takes on the same lightened color similar to the sidebar (primary) appearance. With UITitlebarTitleVisibility set to hidden and if I set the titlebar.toolbar to nil, (which removes the UITitlebar, there is no appearance issue. Running on iPad, with no UITitlebar, there is no odd lightening experienced when the UIHostingController is shown. I think this has something to do with the UIHostingController within Mac Catalyst.
Replies
1
Boosts
0
Views
176
Activity
May ’25
App Name Display
For now, my app name length is more than 20 characters, so the iPhone app name displays without a space, and uses the range operator to ensure showing the rest in the next line. Is it possible to show space and name with 2 lines?
Topic: UI Frameworks SubTopic: General Tags:
Replies
0
Boosts
0
Views
80
Activity
May ’25
Recently used applications on guardian phone - FamilyControls, DeviceActivityReport
For an iOS app that runs in both child and parent mode across iOS devices. On the child device, with Family Controls enabled using .child permissions via AuthorizationCenter.requestAuthorization(for: .child). Is any way to display a list of recently used apps by the child on the parent (guardian) device, in a privacy-preserving and Apple-compliant way?
Replies
1
Boosts
0
Views
146
Activity
May ’25
SwiftUI macOS simple NavigationStack and NavigationLink -> problem on multiplatform project
I had a problem with my app (or in my setup) and searching the web I found a very simple code where part of my problem occurs. I create a new Multiplatform App and paste this code in ContentView. import SwiftUI struct ContentView: View { var body: some View { NavigationStack { VStack { Text("Navigation article") .font(.title) .padding() NavigationLink("Go to the second view", destination: SecondView()) .padding() } .navigationTitle("First View") } } } struct SecondView: View { var body: some View { Text("This is the Second view") .font(.headline) .padding() .navigationTitle("Second View") } } run on iPhone/ iOS no problem run on a Mac/macOS Going from view 1 to view 2 work, the back arrow on view 2 is there, and it is working but the second time I go to the view 2, the back arrow is gone. after looking closely I can see the Arrow Underneath the S of SecondView. I have tried many things and could not make it work. I post this in a HackingWithSwift forum and somebody tried the code and said it work. so it seems the problem could be related to my setup but I create another user in my computer , same problem and tried it on my another computer, same problem.
Topic: UI Frameworks SubTopic: SwiftUI
Replies
7
Boosts
0
Views
93
Activity
Apr ’25
iOS app crash with UIKitcore - UIAlertController
I have recently submitted a new app version to the Appstore with Xcode 15.0. Unfortunately, I have started to see the below crash in the Xcode organiser &gt; Crashes section occurring for more number of times. UIKitCore: +[UIAlertController _alertControllerContainedInViewController:] + 160 The exception trace is not leading to main() function but not pointing to any of the code line. I had used UIAlertController in the past versions to show the alerts but there is no code written in the current version code related to UIAlertController. Only from the latest version, this kind of crash started to surface. In the latest release, We have added a third party SDK and while implementing the SDK, we had added the Location and Bluetooth Permissions in Info.plist file. But as we don't want to use/track the Location and Bluetooth details from the app, the SDK team has disabled the Location and Bluetooth settings to not reflect in the tracked data. Is this behaviour creating any conflict with the UIAlertController and logging the crash? Because by default the OS tries to show the alert when the permissions exist in the plist file, but the alert will not come as the service is disabled on the SDK server settings. Is this creating any conflict and logging the crash. Please extend your help.
Replies
3
Boosts
0
Views
881
Activity
May ’25
Xcode downloads client crash report for NSOutlineView._updateDisclosureButtonForRowView with reason "Segmentation fault" but the stacktraces don't contain any of my app's symbols
All the threads only contain system calls. The crashed thread only contains a single call to my app's code which is main.swift:13. What could cause such a crash? crash.crash
Replies
2
Boosts
0
Views
364
Activity
Apr ’25
How to prevent iOS VoiceOver from speaking accessibility-labels and traits?
I have a button with the following properties: accessibilityLabel: "Action Button", traits: "Button", accessibilityHint: "Performs the main action". The voiceover reads the button as follows: Action Button, Button, Performs the main action. I want to understand how to configure it to only speak the accessibilityHint or only the accessibilityLabel and never speak the traits. In another example, a switch has the traits: Button, and Toggle. So these traits are a part of what the voiceover speaks. I want only the accessibilityLabel or accessibilityHint to be spoken in this case. Please let me know how. Thanks
Replies
1
Boosts
0
Views
132
Activity
May ’25
How to programmatically set cursor position of a text field in SwiftUI
I would like to understand how to programmatically set the position of a cursor in a SwiftUI TextField. In UIKit this can be done using the selectedTextRange property, but I couldn't find a similar way to achieve this with pure SwiftUI. I want to figure out something like setCursorPosition (index:) - maybe by tracking the position in a @State or any other way. I understand that I can do this using UIViewRepresentable but I am looking for a pure SwiftUI solution and wanted to know if there is any.
Replies
2
Boosts
0
Views
463
Activity
Mar ’25
RePlayKit:screen recording method return sampleBuffer is nil
I want record screen in my app,the method startCaptureWithHandler:completionHandler:,the sampleBuffer, It is supposed to exist but it has become nil.Not only that,but there‘s another problem,when I want to stop recording and save the video,I will check [RPScreenRecorder sharedRecorder].recording first, it will be false sometime,that problems are unusual in iOS 18.3.2 iPhoneXs Max,and unexpected,here is my code -(void)startCaptureScreen { NSLog(@"AKA++ startCaptureScreen"); if ([[RPScreenRecorder sharedRecorder] isRecording]) { return; } //屏幕录制 [[RPScreenRecorder sharedRecorder]setMicrophoneEnabled:YES]; NSLog(@"AKA++ MicrophoneEnabled AAAA startCaptureScreen"); [[RPScreenRecorder sharedRecorder]setCameraEnabled:YES]; [[RPScreenRecorder sharedRecorder] startCaptureWithHandler:^(CMSampleBufferRef _Nonnull sampleBuffer, RPSampleBufferType bufferType, NSError * _Nullable error) { if(self.assetWriter == nil){ if (self.AVAssetWriterStatus == 0) { [self setupAssetWriterAndStartWith:sampleBuffer]; } } if (self.AVAssetWriterStatus != 2) { return; } if (error) { // deal with error return; } if (self.assetWriter.status != AVAssetWriterStatusWriting) { [self assetWriterAppendSampleBufferFailWith:bufferType]; return; } if (bufferType == RPSampleBufferTypeVideo) { if(self.assetWriter.status == 0 ||self.assetWriter.status > 2){ } else if(self.videoAssetWriterInput.readyForMoreMediaData == YES){ BOOL success = [self.videoAssetWriterInput appendSampleBuffer:sampleBuffer]; } } if (bufferType == RPSampleBufferTypeAudioMic) { if(self.assetWriter.status == 0 ||self.assetWriter.status > 2){ } else if(self.audioAssetWriterInput.readyForMoreMediaData == YES){ BOOL success = [self.audioAssetWriterInput appendSampleBuffer:sampleBuffer]; } } } completionHandler:^(NSError * _Nullable error) { //deal with error }]; } and than ,when want to save it : -(void)stopRecording { if([[RPScreenRecorder sharedRecorder] isRecording]){ // The problem is sporadic,recording action failed,it makes me confused } [[RPScreenRecorder sharedRecorder] stopCaptureWithHandler:^(NSError * _Nullable error) { if(!error) { //post message } }]; }
Replies
0
Boosts
0
Views
91
Activity
Apr ’25
drag a modelEntity inside an Immersive space and track position
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 RealityKit import RealityKitContent import Foundation @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<Float>? = 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() .targetedToEntity(sphere) .onChanged { _ in self.isDragging = true } .onEnded { _ in self.isDragging = false } } var body: some View { Text("Hello, World!") RealityView { content in //1. Anchor Entity let anchor = AnchorEntity(world: SIMD3<Float>(0, 0, -1)) let ball = sphere //1.2 add component to ball ball.components.set(InputTargetComponent()) //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) } }
Replies
0
Boosts
0
Views
69
Activity
Apr ’25