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
It looks like I'm one of the rare developers dealing with CarPlay...
I develop a CarPlay extension for my apps. A few things:
especially when using the CarPlay I/O window in iOS Simulator, I get random selection highlightning for list items: I have three list templates in a tab template; once I reselect a list using the tab which has been selected before, the initial list item highlights / returns to normal every refresh of the list content; while this doesn't happen for my real world Sony CarPlay device, I'd rather not see such disturbing highlighting for my users. I do not update the template structs or items here, it is just content like text of detailText I update. Question: how to remove highlightning programmatically - especially for devices with touch screen?
I have one user who reports auto-selection of UI elements while driving; I assume this is some problem with his touch screen, but it may be a general issue too. Question: anyone with similar observations
connecting my iPhone to the stand-alone Car Play simulator doesn't work; I had it working before, so it might be related to a recent iOS beta...
Any hints / observations are welcome. The CarPlay community really seems to be small and I'd like to hear other's experience on the named items.
https://github.com/apple/sample-food-truck
Hi! I'm seeing what looks like some weird navigation issue in the Food Truck app. It's from the Live Activity that should deep link to a specific point in the app. There seems be some state where the app is not linking to the correct component. Here are my repro steps on iPhone:
Start live activity from OrderDetailView.
Navigate to Sidebar component.
Tap the Live Activity.
App opens TruckView.
The App should be opening the OrderDetailView for the Order that was passed to the Live Activity. This seems to work when the app is not currently on Sidebar.
Any ideas? I'm testing this on iPhone OS 18.4.1. Is this an issue inside NavigationSplitView? Is this an issue with how Food Truck handles deeplinking?
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
When the perform method of my AppIntent returns the custom view's dialog, and after I click the "Click Test" button, my app will be launched, but this dialog does not close. How can I close it?
struct QuestionResultView: View {
var body: some View {
VStack {
if #available(iOS 17.0, *) {
Button(role:.cancel, intent: OpenAppIntent()) {
Text("Click Test")
}
}
}.frame(height: 300)
}
}
struct OpenAppIntent : AppIntent {
static let title: LocalizedStringResource = "Open my app"
static let openAppWhenRun: Bool = true
static let isDiscoverable: Bool = false;
@MainActor
func perform() async throws -> some IntentResult {
return .result()
}
}
struct OpenPhotoRecognizing: AppIntent {
static let title: LocalizedStringResource = "Read photo"
static let description = IntentDescription("")
static let openAppWhenRun: Bool = false
func perform() async throws -> some IntentResult & ShowsSnippetView & ProvidesDialog{
return .result(dialog: "Demo Test") {
DemoResultView()
}
}
}
Topic:
UI Frameworks
SubTopic:
SwiftUI
iOS 18.4.1
When I change a Google type event to an iCloud type, a "Cannot Save Event" prompt box pops up.
We have also received user feedback that recurring events also fail to save. After updating to iOS 18.4 when trying to save changes to an existing repeating event, the message "Cannot Save Event" will appear.
EventKitUI
Topic:
UI Frameworks
SubTopic:
UIKit
Let's say you have a protocol that can work with both classes and structs but you want to have a uniform UI to make edits.
What is the recommended way to have one view that will take both?
App
import SwiftUI
@main
struct ObservationTesterApp: App {
var body: some Scene {
WindowGroup {
ContentView(existence: Existence())
}
}
}
Types
import Foundation
protocol Dateable {
var timestamp:Date { get set }
}
struct Arrival:Dateable {
var timestamp:Date
}
@Observable
class Existence:Dateable {
var timestamp:Date
init(timestamp: Date) {
self.timestamp = timestamp
}
}
extension Existence {
convenience init() {
self.init(timestamp: Date())
}
}
ContentView, etc
//
// ContentView.swift
// ObservationTester
//
//
import SwiftUI
struct EditDateableView<TimedThing:Dateable>:View {
@Binding var timed:TimedThing
//note that this currently JUST a date picker
//but it's possible the protocol would have more
var body:some View {
DatePicker("Time To Change", selection: $timed.timestamp)
}
}
#Preview {
@Previewable @State var tt = Arrival(timestamp: Date())
EditDateableView<Arrival>(timed: $tt)
}
struct ContentView: View {
@State var arrival = Arrival(timestamp: Date())
@Bindable var existence:Existence
var body: some View {
//this work around also not allowed. "self is immutable"
// let existBinding = Binding<Existence>(get: { existence }, set: { existence = $0 })
VStack {
EditDateableView(timed: $arrival)
//a Binding cant take a Bindable
//EditDateableView<Existence>(timed: $existence)
}
.padding()
}
}
#Preview {
ContentView(existence: Existence())
}
I am working on creating a custom Popup View based on a .fullscreenCover. The .fullscreenCover is used to place the Popup content on screen on a semi-transparent background.
While this works on iOS 18, there is a problem on iOS 17: When the Popup content contains a .sheet, the background is not transparent any more but opaque.
Image: iOS 17. When showing the Popup an opaque background covers the main content. When tapping on the background it turns transparent.
Image: iOS 18. Everything works as intended. When showing the Popup the main background is covered with a semi-transparent background.
Removing the .sheet(...) from the Popup content solves the problem. It does not matter if the sheet is used or not. Adding it to the view code is enough to trigger the problem.
Using a .sheet within a .fullscreenCover should not be a problem as far as I know.
Is this a bug in iOS 17 or is there something wrong with my code?
Code:
struct SwiftUIView: View {
@State var isPresented: Bool = false
@State var sheetPresented: Bool = false
var body: some View {
ZStack {
VStack {
Color.red.frame(maxHeight: .infinity)
Color.green.frame(maxHeight: .infinity)
Color.yellow.frame(maxHeight: .infinity)
Color.blue.frame(maxHeight: .infinity)
}
Button("Show") {
isPresented = true
}
.padding()
.background(.white)
Popup(isPresented: $isPresented) {
VStack {
Button("Dismiss") {
isPresented = false
}
}
.frame(maxWidth: 300)
.padding()
.background(
RoundedRectangle(cornerRadius: 20)
.fill(.white)
)
.sheet(isPresented: $sheetPresented) {
Text("Hallo")
}
}
}
}
}
struct Popup<Content: View>: View {
@Binding var isPresented: Bool
let content: () -> Content
init(isPresented: Binding<Bool>, @ViewBuilder _ content: @escaping () -> Content) {
_isPresented = isPresented
self.content = content
}
@State private var internalIsPresented: Bool = false
@State private var isShowing: Bool = false
let transitionDuration: TimeInterval = 0.5
var body: some View {
ZStack { }
.fullScreenCover(isPresented: $internalIsPresented) {
VStack {
content()
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(
Color.black.opacity(0.5)
.opacity(isShowing ? 1 : 0)
.animation(.easeOut(duration: transitionDuration), value: isShowing)
.ignoresSafeArea()
)
.presentationBackground(.clear)
.onAppear {
isShowing = true
}
.onDisappear {
isShowing = false
}
}
.onChange(of: isPresented) { _ in
withoutAnimation {
internalIsPresented = isPresented
}
}
}
}
extension View {
func withoutAnimation(action: @escaping () -> Void) {
var transaction = Transaction()
transaction.disablesAnimations = true
withTransaction(transaction) {
action()
}
}
}
Topic:
UI Frameworks
SubTopic:
SwiftUI
In my CarPlay app, I am hiding the navigation bar by using the following:
self.mapTemplate?.automaticallyHidesNavigationBar = true
self.mapTemplate?.hidesButtonsWithNavigationBar = false
I don't want the navigation bar to show unless a user interacts with the map by tapping it.
Strangely, when I present a CPNavigationAlert the navigation bar will often appear and then disappear after the alert is dismissed.
Is there a setting or reason that the navigation bar would be appearing when presenting this alert? I would like to keep the nav bar hidden during this time.
I’m having a weird UIKit problem. I have a bunch of views in a UIScrollView and I add a UIContextMenuInteraction to all of them when the view is first loaded. Because they're in a scroll view, only some of the views are initially visible.
The interaction works great for any of the views that are initially on-screen, but if I scroll to reveal new subviews, the context menu interaction has no effect for those.
I used Xcode's View Debugger to confirm that my interaction is still saved in the view's interactions property, even for views that were initially off-screen and were then scrolled in.
What could be happening here?
Hi, I'm working on RealityView and I have two entities in RCP. In order to set views for both entities, I have to create two separate attachments for each entity. What I want to achieve is that when I hover (by eye) on one entity's attachment, it would trigger the hover effect of the other entity's attachment. I try to use the hoverEffectGroup, but it would only activate the hover effect in a subview, instead a complete separate view. I refer to the following WWDC instruction for the hover effect.
https://developer.apple.com/videos/play/wwdc2024/10152/
We've seen a spike in crashes on iOS 18.4 across both iPhone & iPad. We can't reproduce it, but it looks like it happens when the app goes into the background.
Crash Log
DESCRIPTION OF PROBLEM
When using SwiftUI’s TextField or TextEditor on iPadOS, a persistent gray or default system material bar appears at the bottom of the screen. This gray bar is not present in Apple’s native apps (such as Notes, Mail, Messages) or in third-party apps like ChatGPT and Beeper
STEPS TO REPRODUCE
Create a TextField or TextEditor. Run the code, click on it, without software keyboard enabled.
I have setup the extension for replaykit successfully , the bundle id and everything is correct but still the system broadcast picker view is not showing my own app to broadcast screen content when trying to do system wide broadcast.
Device: iPhone 16 Pro Max
System Version: 18.3.1
Screen width and height obtained using [UIScreen mainScreen].bounds.size are as follows
Why are the two results different?
App update in which there were no changes regarding the widget. Just after it updated, the widget turns black in some cases. It also appears black in the widget gallery. Removing and adding it again did not work in this case, only after an iOS restart it works fine again
This is the log
2025-03-20 02:14:05.961611 +0800 Content load failed: unable to find or unarchive file for key: [com.aa.bb::com.aa.bb.widget:cc_widget:systemMedium::360.00/169.00/23.00:(null)~(null)] on no host. The session may still produce one shortly. Error: Using url file:///private/var/mobile/Containers/Data/PluginKitPlugin/51C5E4F2-6F1F-4466-A428-73C73B9CC887/SystemData/com.apple.chrono/placeholders/cc_widget/systemMedium----360.00w--169.00h--23.00r--1f--0.00t-0.00l-0.00b0.00t.chrono-timeline ... Error Domain=NSCocoaErrorDomain Code=4 "file“systemMedium----360.00w--169.00h--23.00r--1f--0.00t-0.00l-0.00b0.00t.chrono-timeline”not exist。" UserInfo={NSFilePath=/private/var/mobile/Containers/Data/PluginKitPlugin/51C5E4F2-6F1F-4466-A428-73C73B9CC887/SystemData/com.apple.chrono/placeholders/cc_widget/systemMedium----360.00w--169.00h--23.00r--1f--0.00t-0.00l-0.00b0.00t.chrono-timeline, NSUnderlyingError=0xa693d3a80 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}
Subject: SwiftUI Gesture Conflict in iOS 18: Simultaneous Recognition of Drag and Tap Gestures
Description:
In SwiftUI on iOS 18 and above, we've identified an issue with gesture handling that affects user experience. When implementing .simultaneousGesture(DragGesture()), the system incorrectly recognizes and processes both drag and tap gestures concurrently, resulting in unintended behavior.
Technical Details:
Environment: SwiftUI, iOS 18+
Issue: Simultaneous recognition of horizontal drag gestures and vertical scroll/tap gestures
Current Behavior: Both vertical and horizontal scrolling occur simultaneously when using .simultaneousGesture(DragGesture())
Expected Behavior: Gestures should be properly disambiguated to prevent concurrent scrolling in multiple directions
Impact:
This behavior significantly impacts user experience, particularly in custom carousel implementations and other UI components that rely on precise gesture handling. The simultaneous recognition of both gestures creates a confusing and unpredictable interaction pattern.
Steps to Reproduce:
Create a SwiftUI view with horizontal scrolling (e.g., custom carousel)
Implement .simultaneousGesture(DragGesture())
Add tap gesture recognition to child views
Run on iOS 18
Attempt to scroll horizontally
Observed Result:
Both horizontal dragging and vertical scrolling/tapping are recognized and processed simultaneously, creating an inconsistent user experience.
Expected Result:
The system should properly disambiguate between horizontal drag gestures and vertical scroll/tap gestures, allowing only one type of gesture to be recognized at a time based on the user's intent.
Please let me know if you need any additional information or reproduction steps.
I have received permission from Apple to access SensorKit data for my app. I have granted all necessary permissions, but no data is being retrieved.
The didCompleteFetch method is being called, but I’m unsure where to find event data like Device Usage and Ambient Light. Additionally, the didFetchResult method is never called.
Could anyone please assist me in resolving this issue? Any guidance or troubleshooting steps would be greatly appreciated.
import SensorKit
class ViewController: UIViewController, SRSensorReaderDelegate {
let store = SRSensorReader(sensor: .deviceUsageReport)
override func viewDidLoad() {
super.viewDidLoad()
requestSensorAuthorization()
}
func requestSensorAuthorization() {
var sensors: Set<SRSensor> = [
.accelerometer,
.deviceUsageReport,
.messagesUsageReport,
.visits,
.keyboardMetrics,
.phoneUsageReport,
.ambientLightSensor
]
if #available(iOS 16.4, *) {
sensors.insert(.mediaEvents)
}
SRSensorReader.requestAuthorization(sensors: sensors) { error in
if let error = error {
print("Authorization failed: \(error.localizedDescription)")
} else {
self.store.startRecording()
self.requestSensorData()
print("Authorization granted for requested sensors.")
}
}
}
func requestSensorData() {
let fromTime = SRAbsoluteTime.fromCFAbsoluteTime(_cf: Date().addingTimeInterval(-60 * 60).timeIntervalSinceReferenceDate)
let toTime = SRAbsoluteTime.fromCFAbsoluteTime(_cf: Date().timeIntervalSinceReferenceDate)
let request = SRFetchRequest()
request.from = fromTime
request.to = toTime
request.device = SRDevice.current
store.fetch(request)
store.delegate = self
}
func sensorReader(_ reader: SRSensorReader, didCompleteFetch fetchRequest: SRFetchRequest) {
print("Fetch request completed: \(fetchRequest.from) to \(fetchRequest.to)")
Task {
do {
let samples = try await reader.fetch(fetchRequest)
print("Samples count: \(samples)")
} catch {
print("Error Fetching Data: \(error.localizedDescription)")
}
}
}
func sensorReader(_ reader: SRSensorReader, fetching fetchRequest: SRFetchRequest, didFetchResult result: SRFetchResult<AnyObject>) -> Bool {
print(result)
return true
}
}
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?
Previously, I sorted my FetchResult in a TableView like this:
@FetchRequest(
sortDescriptors: [SortDescriptor(\.rechnungsDatum, order: .forward)],
predicate: NSPredicate(format: "betragEingang == nil OR betragEingang == 0")
)
private var verguetungsantraege: FetchedResults<VerguetungsAntraege>
...
body
...
Table(of:VerguetungsAntraege.self, sortOrder: $verguetungsantraege.sortDescriptors) {
TableColumn("date", value:\.rechnungsDatum) { item in
Text(Formatters.dateFormatter.string(from: item.rechnungsDatum ?? Date()) )
}
.width(120)
TableColumn("rechNrKurz", value:\.rechnungsNummer) { item in
Text(item.rechnungsNummer ?? "")
}
.width(120)
TableColumn("betrag", value:\.totalSum ) {
Text(Formatters.currencyFormatter.string(from: $0.totalSum as NSNumber) ?? "kein Wert")
}
.width(120)
TableColumn("klient") {
Text(db.getKlientNameByUUID(id: $0.klient ?? UUID(), moc: moc))
}
} rows: {
ForEach(Array(verguetungsantraege)) { antrag in
TableRow(antrag)
}
}
There seem to be changes here in Xcode 26. In any case, I always get the error message in each line with TableColumn("title", value: \.sortingField)
Ambiguous use of 'init(_:value:content:)'
Does anyone have any idea what's changed? Unfortunately, the documentation doesn't provide any information.