In SwiftUI for macOS, how can I animate the transition from one Tab to another Tab within TabView when the selection changes?
In AppKit, we can do the following:
let tabViewController = NSTabViewController()
tabViewController.transitionOptions = [.crossfade, .allowUserInteraction]
How can I achieve the same crossfade effect when using TabView?
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.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
Dear all,
Sorry if the topic has already been commented but I could not be able to find it in over 10,000 picks using the forum search field...
My problem is that with any NSTextField in my app, a click will result in a memory leak. There is no code attached, just bindings to NSNumber properties. How can I fix this ?
Thanks for your help.
Best regards
Chris
Topic:
UI Frameworks
SubTopic:
AppKit
QuickTime recording palette behaves in a way which I want to replicate in my desktop app - specifically the behaviour when switching spaces, it appears on top. Currently, my app appears on all spaces, and even over fullscreen applications BUT it already exists when I switch to the space, this feels disjointed.
I can't find a solution to this behaviour. Here's the Window Collection Behaviours I've tried (on an NSPanel):
FullScreenAuxiliary - appears over fullscreen apps.
CanJoinAllSpaces - appears on all spaces.
These two options make the dock show up on all spaces in the same position, but on each space they already exists.
I've tried this behaviour too:
MoveToActiveSpace - which as per docs would move the window into active space only when its reopened, mine stays open all the time.
I can't find any more information on how QuickTime achieves this.
Topic:
UI Frameworks
SubTopic:
SwiftUI
I'm implementing a Map with user location customization in SwiftUI using iOS 17+ MapKit APIs. When using the selection parameter with Map, the default blue dot user location becomes tappable but shows an empty annotation view. However, using UserAnnotation makes the location marker non-interactive.
My code structure:
import SwiftUI
import MapKit
struct UserAnnotationSample: View {
@State private var position: MapCameraPosition = .userLocation(fallback: .automatic)
@State private var selectedItem: MapSelection<MKMapItem>?
var body: some View {
Map(position: $position, selection: $selectedItem) {
// UserAnnotation()
}
.mapControls {
MapUserLocationButton()
}
}
}
Key questions:
How can I replace the empty annotation view with a custom avatar when tapping the user location?
Is there a way to make UserAnnotation interactive with selection?
Should I use tag modifier for custom annotations? What's the proper way to associate selections?
Hi everyone,
we’d appreciate your input on the following use case – thanks in advance!
In our iPhone and Apple Watch app, we’re using the NearbyInteraction API to measure the distance between both devices via UWB.
Setup:
On the iPhone, we start a LiveActivity together with the NISession, to keep the ranging active in the background.
✅ Good news: On iOS 18.4, this works as expected – the NISession stays active in the background as long as the Live Activity is running.
Current issues:
As soon as the Watch app moves to the background, ranging seems to pause and is eventually terminated.
→ Question 1: Is there a way to keep the NISession active on the Watch when the app goes into the background?
Audio playback from background not working:
We'd like to trigger audio playback when certain distance changes are detected. So far, we can only trigger haptic feedback in the background – audio does not play.
→ Question 2: Is it possible to play audio (e.g. using AVAudioPlayer) while a NISession and a LiveActivity are running in the background?
We’d be grateful for any advice or best practices for this combination.
Thanks and best regards!
Topic:
UI Frameworks
SubTopic:
General
Xcode 16 iOS18 WKWebView里包含http图片时无法显示
Topic:
UI Frameworks
SubTopic:
UIKit
I have a simple Picker where the options available change by the view state. I would like to have the transition animated but the default animation is not good so I tried setting a .transition() and or an .animation() inside an item on the picker but it is ignored. The same happens if the transition is set on the picker itself since it's always present.
Am I doing it right and is just not posible or is there something else to do?
Code to reproduce the issue:
struct ContentView: View {
@State var list: [String] = [
"Item 4",
"Item 5",
"Item 6",
"Item 7",
"Item 8",
]
@State var selected: String?
@State var toggle: Bool = false
var body: some View {
VStack {
Picker("List", selection: $selected) {
ForEach(list, id: \.self) {
Text($0).tag($0)
// .transition(.opacity)
}
}
.pickerStyle(.segmented)
// .transition(.opacity)
HStack {
Button(action: swapOptions) {
Text("Swap")
}
}
}
.padding()
}
}
extension ContentView {
func swapOptions() {
withAnimation {
toggle.toggle()
switch toggle {
case true:
list = [
"Item 1",
"Item 2",
"Item 3",
"Item 4",
"Item 5",
]
case false:
list = [
"Item 4",
"Item 5",
"Item 6",
"Item 7",
"Item 8",
]
}
}
}
}
``
Topic:
UI Frameworks
SubTopic:
SwiftUI
I am working on implementing a new Intents UI Extension and have noticed that when it is triggered via the "Hey Siri" voice command, the intent dismisses after a few seconds. However, if it is launched from the Shortcuts app, the intent remains active and does not dismiss automatically.
Additionally, I’ve observed that this behavior occurs on specific iOS versions, such as 17.5.1 or 17.7. On other versions, like 17.4.1 or 18.4, the intent persists as expected.
Does Siri automatically close the intent based on its own logic? Could the iOS version be influencing this behavior? Given the requirement to make the intent persistent, is there any option or configuration available to achieve this?
Something func applicationWillEnterForeground is not getting called for specific iOS 18.3.2
Topic:
UI Frameworks
SubTopic:
UIKit
Description:
When initiating the print flow via UIPrintInteractionController, and no printer is initially connected, iOS displays all possible paper sizes in the paper selection UI. However, if a printer connects in the background after this view is shown, the list of paper sizes does not automatically refresh to reflect only the options supported by the connected printer.
If the user selects an incompatible paper size (one not supported by the printer that has just connected), the app crashes due to an invalid configuration.
Steps to Reproduce:
Launch the app and navigate to the print functionality.
Tap the Print button to invoke UIPrintInteractionController.
At this point, no printer is yet connected. iOS displays all available paper sizes.
While the paper selection UI is visible, the AirPrint-compatible printer connects in the background.
Without dismissing the controller, the user selects a paper size (e.g., one that is not supported by the printer).
The app crashes.
Expected Result: App should not crash
Once the printer becomes available (connected in the background), the paper size options should refresh automatically.
The list should be filtered to only include sizes that are compatible with the connected printer.
This prevents the user from selecting an invalid option, avoiding crashes.
Actual Result: App crashes
The paper size list remains unfiltered.
The user can still select unsupported paper sizes.
Selecting an incompatible option causes the app to crash, due to a mismatch between UI selection and printer capability.
Topic:
UI Frameworks
SubTopic:
UIKit
I have a popover/sheet in iOS which allows users to search and add items to a list. When the sheet is shown, the search should always be active.
I am using searchable on a NavigationStack inside the sheet. I am using the isPresented parameter to activate search.
My issue is with the animation of the search activation. Even if I use...
isPresented: .constant(true)
...the search isn't activated until the sheet has completed it's entrance animation, resulting in two stages of animation.
I can't add a video here, but the two images below show the steps I am seeing. First a slide up animation, with the search in the navigation drawer, then a second animation, once the sheet is fully in place, as the search becomes active.
Is it possible to merge these two animations, so search is in place when the sheet animates up?
Topic:
UI Frameworks
SubTopic:
SwiftUI
I have created an AppIntent and added it to shortcuts to be able to read by Siri. When I say the phrase, the Siri intent dialog appears just fine. I have added a custom SwiftUI View inside Siri dialog box with 2 buttons with intents. The callback or handling of those buttons is not working when initiated via Siri. It works fine when I initiate it in shortcuts. I tried using the UIButton without the intent action as well but it did not work. Here is the code.
static let title: LocalizedStringResource = "My Custom Intent"
static var openAppWhenRun: Bool = false
@MainActor
func perform() async throws -> some ShowsSnippetView & ProvidesDialog {
return .result(dialog: "Here are the details of your order"), content: {
OrderDetailsView()
}
}
struct OrderDetailsView {
var body: some View {
HStack {
if #available(iOS 17.0, *) {
Button(intent: ModifyOrderIntent(), label : {
Text("Modify Order")
})
Button(intent: CancelOrderIntent(), label : {
Text("Cancel Order")
})
}
}
}
}
struct ModifyOrderIntent: AppIntent {
static let title: LocalizedStringResource = "Modify Order"
static var openAppWhenRun: Bool = true
@MainActor
func perform() async throws -> some OpensIntent {
// performs the deeplinking to app to a certain page to modify the order
}
}
struct CancelOrderIntent: AppIntent {
static let title: LocalizedStringResource = "Cancel Order"
static var openAppWhenRun: Bool = true
@MainActor
func perform() async throws -> some OpensIntent {
// performs the deeplinking to app to a certain page to cancel the order
}
}
Button(action: {
if let url = URL(string: "myap://open-order") {
UIApplication.shared.open(url)
}
}
Hi,
I am currently developing a document-based application for macOS and have encountered a challenge related to document container management. Specifically, I need to open a windowGroup that shares the same container as the one used in the DocumentGroup. However, my current approach of using a global shared model container has led to unintended behavior: any new document created is linked to existing ones, and changes made in one document are reflected across all documents.
To address this issue, I am looking for a solution that allows each newly created document to be individualized while still sharing the document container with all relevant WindowGroups that require access to the data it holds. I would greatly appreciate any insights or recommendations you might have on how to achieve this.
Thank you for your time and assistance.
Best regards,
Something like:
@main
struct Todo: App {
var body: some Scene {
DocumentGroup(editing: Item.self, contentType: .item) {
ContentView()
}
WindowGroup {
UndockView()
.modelContainer(of documentGroup above)
}
}
}
We recently migrated our app to use NavigationSplitView on iPad with a sidebar and detail setup, and we got reports that the navigation buttons on the sidebar disappear when returning to our app after using a different app. I reproduced the issue from a new empty project with the following code (issue tested on iOS 17.4 and iOS 18.3, was not able to reproduce on iOS 16.4):
import SwiftUI
@main
struct TestApp: App {
var body: some Scene {
WindowGroup {
NavigationSplitView {
Text("sidebar")
.toolbar {
ToolbarItem(placement: .topBarLeading) {
Button(action: {}) {
Image(systemName: "square.and.arrow.down")
}
}
ToolbarItem(placement: .topBarTrailing) {
Button(action: {}) {
Image(systemName: "square.and.arrow.up")
}
}
}
} detail: {
Text("detail")
.toolbar {
ToolbarItem(placement: .topBarLeading) {
Button(action: {}) {
Image(systemName: "eraser")
}
}
ToolbarItem(placement: .topBarTrailing) {
Button(action: {}) {
Image(systemName: "pencil")
}
}
}
}
}
}
}
Please check the following GIF for the simple steps, notice how the navbar buttons in the detail view do not disappear:
Here's the console output, it shows that the constraints break internally:
Hi! I'm seeing some weird animation issues building the Food Truck sample application.^1 I'm running from macOS 15.4 and Xcode 16.3. I'm building the Food Truck application for macOS. I'm not focusing on iOS for now.
The FoodTruckModel adds new Order values with an animation:
// FoodTruckModel.swift
withAnimation(.spring(response: 0.4, dampingFraction: 1)) {
self.orders.append(orderGenerator.generateOrder(number: orders.count + 1, date: .now, generator: &generator))
}
This then animates the OrdersTable when new Order values are added.
Here is a small change to OrdersTable:
// OrdersTable.swift
- @State private var sortOrder = [KeyPathComparator(\Order.status, order: .reverse)]
+ @State private var sortOrder = [KeyPathComparator(\Order.creationDate, order: .reverse)]
Running the app now inserts new Order values at the top.
The problem is I seem to be seeing some weird animation issues here. It seems that as soon as the new Order comes in there is some kind of weird glitch where it appears as if part the animation is coming from the side instead of down from the top:
What's then more weird is that if I seem to affect the state of the Table in any way then the next Order comes in with perfect animation.
Scrolling the Table fixes the animation.
Changing the creationData sort order from reverse to forward and back to reverse fixes the animation.
Any ideas? Is there something about how the Food Truck product is built that would cause this to happen? Is this an underlying issue in the SwiftUI infra?
Hi,
I am trying to create a local backup + restore when using SwiftUI and CoreData but I am facing errors left and right. the latest error I am stuck on is:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'executeFetchRequest:error: A fetch request must have an entity.'
Here is what am trying to do:
Creating a backup (already solved using NSPersistentStoreCoordinator.migratePersistentStore(_:to:options:type:))
Create a new NSPersistentContainer and call its NSPersistentContainer.loadPersistentStores(completionHandler:) (already solved, load is successful)
Update the .environment(.managedObjectContext, viewModel.context) so that SwiftUI uses the new context. (HERE is where the error appears)
Any help would be appreciated.
Here is some sample code of SwiftUI part of the main view:
class ViewModel: ObservableObject {
@Published var context: NSManagedObjectContext
}
@main
struct MyApp: App {
@StateObject var viewModel: ViewModel
var body: some Scene {
WindowGroup {
ContentView()
.environment(\.managedObjectContext, viewModel.context)
}
}
}
Topic:
UI Frameworks
SubTopic:
SwiftUI
I am new to the idea of Siri Shortcuts and App Intents. What I want to do is use Siri to run a function in my app.
Such as saying to Siri Zoom in map and that will then call a function in my app where I can zoom in the map. Similarly, I could say Zoom out map and it would call a function to zoom out my map.
I do not need to share any sort of shortcut with the Shortcuts app.
Can someone please point me in the right direction for what type of intents I need to use for this?
Description
When using UIDocumentPickerViewController with allowsMultipleSelection = false, I expect that selecting a file will dismiss only the document picker.
However, if a user quickly taps the same file multiple times, the picker dismisses both itself and the presenting view controller (i.e., it pops two levels from the view controller stack), which leads to unintended behavior and breaks presentation flow.
Expected Behavior
Only UIDocumentPickerViewController should be dismissed when a file is selected—even if the user taps quickly or multiple times on the same file.
Actual Behavior
When tapping the same file multiple times quickly, the picker dismisses not only itself but also the parent view controller it was presented from.
Steps to Reproduce
Create a simple view controller and present another one modally over it.
From that presented view controller, present a UIDocumentPickerViewController with allowsMultipleSelection = false.
Tap quickly on the same file in the picker 2 times.
Result: Both the document picker and the presenting view controller are dismissed.
Reproducible Code Snippet
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .green
addLabel("Parent View Controller")
DispatchQueue.main.async { [unowned self] in
let child = UIViewController()
child.view.backgroundColor = .yellow
present(child, animated: true)
child.addLabel("Child View Controller")
let vc = UIDocumentPickerViewController(
forOpeningContentTypes: [.pdf, .jpeg, .png],
asCopy: true
)
vc.allowsMultipleSelection = false
child.present(vc, animated: true)
}
}
}
extension UIViewController {
func addLabel(_ text: String) {
let label = UILabel(frame: CGRect(x: 0, y: 50, width: view.bounds.width, height: 30))
label.text = text
view.addSubview(label)
}
}
Environment
Device: iPhone 15 Pro and others
iOS version: 18.2 (reproduces on multiple iOS versions)
Occurs with: .pdf, .jpeg, .png file types
Mode: Both simulator and real device
Notes
Happens consistently with fast multiple taps on the same file.
This breaks expected view controller stack behavior.
I want to record screen ,and than when I call the method stopCaptureWithHandler:(nullable void (^)(NSError *_Nullable error))handler to stop recording and saving file. before call it,I check the value record of RPScreenRecorder sharedRecorder ,the value is false , It's weird! The screen is currently being recorded !
I wonder if the value of [RPScreenRecorder sharedRecorder].record will affect the method stopCaptureWithHandler:
-(void)startCaptureScreen {
[[RPScreenRecorder sharedRecorder] startCaptureWithHandler:^(CMSampleBufferRef _Nonnull sampleBuffer, RPSampleBufferType bufferType, NSError * _Nullable error) {
//code
} completionHandler:^(NSError * _Nullable error) {
//code
}];
}
- (void)stopRecordingHandler {
if([[RPScreenRecorder sharedRecorder] isRecording]){
// deal error .sometime isRecording is false
}else {
[[RPScreenRecorder sharedRecorder] stopCaptureWithHandler:^(NSError * _Nullable error) {
}];
}
}
here are my code.
I have a UITextView being added at runtime to a UIImageView as the result of doing text recognition. It's set to be editable = NO and selectable = YES. When I set the text and select it, it asks the delegate for the menu to display via:
textView:editMenuForTextInRange:suggestedActions:
The suggested items contains many UIAction and UICommand objects that have private methods or do not have the destructive attribute set, yet they are destructive. Some of these are:
promptForReplace:
transliterateChinese:
_insertDrawing:
_showTextFormattingOptions:
I need to return a menu that has only non-destructive commands in it.
First, why isn't UITextView sending only non-destructive suggested commands when its editable is NO?
Second, how can I filter the array of suggested commands when it's impossible to know if they're destructive (as some are missing that attribute)?
In addition to that, even non-destructive commands are causing an unrecognized selector exception, such as the Speak command, which it is sending to my view controller instead of to the UITextView, which is the only thing that knows what the text is that it should speak.
Topic:
UI Frameworks
SubTopic:
UIKit