We are looking at the possibility of launching our app through Siri with a locked device. We have the device responding to our App Intent but it is asking to be unlocked first. If the device is locked the intent works perfectly. It just doesn't seem to respect the set intentAuthenticationPolicy.
Thank you for you time looking into this.
We have set these var to .alwaysAllowed and open to true.
static var authenticationPolicy: IntentAuthenticationPolicy = .alwaysAllowed
static var openAppWhenRun: Bool = true
Here is our full test code:
import AppIntents
import SwiftUI
// MARK: - App Intents
struct OpenAppIntent: AppIntent {
static var title: LocalizedStringResource = "Open Main App"
static var description: IntentDescription? = .init(stringLiteral: "Opens the App")
static var authenticationPolicy: IntentAuthenticationPolicy = .alwaysAllowed
static var openAppWhenRun: Bool = true
func perform() async throws -> some IntentResult {
print("App opened")
return .result()
}
}
struct TestAppShortcutProvider: AppShortcutsProvider {
static var appShortcuts: [AppShortcut] {
AppShortcut(
intent: OpenAppIntent(),
phrases: [
"Begin \(.applicationName)"
],
shortTitle: "Open App",
systemImageName: "popcorn.fill"
)
}
}
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
I have found a system bug with UINavigationController, UIGestureRecognizerDelegate mainly the swipe back control.
I have reproduced this in many apps, while some that use custom swipe back i can not reproduce, however any app using default uikit/swift transitions i can reproduce the flicker/previous screen flashing
The Bug: a slight tap or series of quick taps anywhere on the screen (with the slightest (1-2pt -x)confuse the system into thinking its a swipe back gesture, however instead of pushing back to previous screen the UI flickers and flashes the previous screen. for a split second, very easy to reproduce.
on screens with lots of options of boxes to tap it happens quite often.
I have removed all custom "swipe back from anywhere" logic, all custom gesture logic, and can still reproduce by tapping the edge of the screen
with only UINavigationController, UIGestureRecognizerDelegate in my navigation controller.
Please let me know the best way to get in contact with someone at apple to either build an extension to prevent this flicker or if a developer has a fix but this is rarely talked about. (velocity limits etc do not work, and just make the gesture feel awful)
all the developers i have reached out too have looked into this and have said "its an ios bug, only fix is build a custom swipe back from anywhere, or wait for apple to fix it).... as a small indie app, building my own seems daunting
Recap: quick or taps with small x movement flash previous screen instead of pushing back or simply recognizing it as a tap and not flashing previous screen. this happens with no custom code default uikit/swift. Link me your app i can probably reproduce it, I have reproduced it in X(was hard), Retro(easy), and many more.
The goal is to have a smooth native swipe/drag back from anywhere gesture while preventing flicking on fast taps or short taps with minor x movement. i have tried everything from setting limits to -x, velocity limits etc. nothing fixes this.
happy hacking!
PS i hope someone at apple calls me and i can explain this and we can fix it for every app in an update.
import SwiftUI
struct Product: Identifiable {
let id = UUID()
let name: String
let pricePerKg: Double
}
struct ContentView: View {
@State private var selectedProduct: Product?
@State private var quantity: Double = 1.0
@State private var orderDate = Date()
@State private var showingConfirmation = false
let products = [
Product(name: "Lamb", pricePerKg: 15.0),
Product(name: "Beef", pricePerKg: 20.0),
Product(name: "Chicken", pricePerKg: 10.0)
]
var body: some View {
NavigationView {
Form {
Section(header: Text("Select Meat")) {
Picker("Meat Type", selection: $selectedProduct) {
ForEach(products) { product in
Text(product.name).tag(product as Product?)
}
}
}
if let selectedProduct = selectedProduct {
Section(header: Text("Quantity (kg)")) {
Stepper(value: $quantity, in: 0.5...10, step: 0.5) {
Text("\(quantity, specifier: "%.1f") kg")
}
}
Section(header: Text("Delivery Date")) {
DatePicker("Select Date", selection: $orderDate, in: Date()..., displayedComponents: .date)
}
Section(header: Text("Total Price")) {
Text("$\(selectedProduct.pricePerKg * quantity, specifier: "%.2f")")
}
Button("Confirm Order") {
showingConfirmation = true
}
.alert(isPresented: $showingConfirmation) {
Alert(title: Text("Order Confirmed"), message: Text("You have ordered \(quantity, specifier: "%.1f") kg of \(selectedProduct.name) for \(orderDate.formatted(date: .long, time: .omitted))."), dismissButton: .default(Text("OK")))
}
}
}
.navigationTitle("Halal Butcher")
}
}
}
@main
struct HalalButcherApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
I'm trying to make one of my segments disable and configure different font color.
I'm able to achieve it by using .selectionDisabled(), which is only available in iOS 17 +.
I am wondering if there's an alternative for iOS 16.
Thank you
import SwiftUI
struct MySegment: Hashable {
let label: String
let isDisabled: Bool
}
struct MySegmentedControlView: View {
@State var selection: String = "item1"
let data: [MySegment] = [
MySegment(label: "item1", isDisabled: false),
MySegment(label: "item2", isDisabled: false),
MySegment(label: "item3", isDisabled: true)
]
init() {
UISegmentedControl.appearance().backgroundColor = .red.withAlphaComponent(0.15)
UISegmentedControl.appearance().selectedSegmentTintColor = .red
UISegmentedControl.appearance().setTitleTextAttributes([.foregroundColor: UIColor.white], for: .selected)
UISegmentedControl.appearance().setTitleTextAttributes([.foregroundColor: UIColor.gray], for: .normal)
UISegmentedControl.appearance().setTitleTextAttributes([.foregroundColor: UIColor.systemGray6], for: .disabled)
}
var body: some View {
VStack {
Picker("", selection: $selection) {
ForEach(data, id: \.label) {
if #available(iOS 17.0, *) {
Text($0.label)
.selectionDisabled($0.isDisabled)
} else {
Text($0.label)
.tag($0.label)
.disabled($0.isDisabled)
}
}
}
.pickerStyle(.segmented)
}
.padding()
}
}
Topic:
UI Frameworks
SubTopic:
SwiftUI
I am facing same issue with major crash while coming out from this function.
Basically using collectionView.dequeReusableCell with size calculation.
func getSizeOfFavouriteCell(_ collectionView: UICollectionView, at indexPath: IndexPath, item: FindCircleInfoCellItem) -> CGSize { guard let dummyCell = collectionView.dequeueReusableCell( withReuseIdentifier: TAButtonAddCollectionViewCell.reuseIdentifier, for: indexPath) as? TAButtonAddCollectionViewCell else { return CGSize.zero }
dummyCell.title = item.title
dummyCell.subtitle = item.subtitle
dummyCell.icon = item.icon
dummyCell.layoutIfNeeded()
var targetSize = CGSize.zero
if viewModel.favoritesDataSource.isEmpty.not,
viewModel.favoritesDataSource.count > FindSheetViewControllerConstants.minimumFavoritesToDisplayInSection {
targetSize = CGSize(width: collectionView.frame.size.width / 2, height: collectionView.frame.height)
var estimatedSize: CGSize = dummyCell.systemLayoutSizeFitting(targetSize)
if estimatedSize.width > targetSize.width {
estimatedSize.width = targetSize.width
}
return CGSize(width: estimatedSize.width, height: targetSize.height)
}
}
We have resolve issue with size calculation with checking nil. Working fine in xcode 15 and 16+.
Note: Please help me with reason of crash? Is it because of xCode 16.2 onwards **strict check on UICollectionView **
I released an app for iPhone (and it's could be downloaded for iPad also), and now I developered another app for iPad version with the same code and logic but I modified the layout to fit bigger screen and make better user experience and appearance.
Howevert the app review rejected my release due to the duplicate content, how can I solve it?
Topic:
UI Frameworks
SubTopic:
General
I have an app with two file types with the following extensions:
gop (an exported type),
sgf (an imported type).
The Save command fails after the following sequence of events:
I open a gop file, say the file "A.gop".
I save this file as an sgf file, say "A.sgf".
This Save As works perfectly and the document name in the document’s title bar has changed to "A.sgf".
I change something in the document and then try to Save this change.
This should just resave the document to "A.sgf", but "A.sgf" remains untouched. Instead I get a system alert with the message
The document “A.sgf” could not be saved. A file with the name “A.gop” already exists. To save the file, either provide a different name, or move aside or delete the existing file, and try again.
In the Xcode console I get the following diagnostic:
NSFileSandboxingRequestRelatedItemExtension: an error was received from pboxd instead of a token. Domain: NSPOSIXErrorDomain, code: 2 [NSFileCoordinator itemAtURL:willMoveToURL:] could not get a sandbox extension. oldURL: file:///Users/francois/Desktop/A.sgf, newURL: file:///Users/francois/Desktop/A.gop
The problem seems to relate to the sandbox. But I am at a loss to find a solution. (After closing the alert, I check that A.sgf did not register the change.)
If I open an sgf file, say "B.sgf", save it as "B.gop", make a change in the document and then try to save this change (into "B.gop"), I hit the same problem, with "gop" and "sgf" interchanged.
If, instead of saving "A.gop" as "A.sgf", I save it as "B.sgf", make a change in the document and then try to save this change into "B.sgf", I get the following system alert:
The document “B.sgf” could not be saved. You don’t have permission. To view or change permissions, select the item in the Finder and choose File > Get Info.
And in the Xcode console I get the following diagnostic:
NSFileSandboxingRequestRelatedItemExtension: an error was received from pboxd instead of a token. Domain: NSPOSIXErrorDomain, code: 2 [NSFileCoordinator itemAtURL:willMoveToURL:] could not get a sandbox extension. oldURL: file:///Users/francois/Desktop/B.sgf, newURL: file:///Users/francois/Desktop/B.gop
Again the sandbox ! (After closing the alert, I check that B.sgf did not register the change.)
It’s clear my code is missing something, but what?
tl;dr can we use Label(application token) inside of a DeviceActivityReport?
I’m working on an app that uses the DeviceActivityReport extension to show a user’s screen time breakdown. The app was working fine in a setup where my main app had the Distribution Family Controls capability and all the extensions had the Development Family Controls capability. However, this caused provisioning issues when I tried to create a test flight build.
I then removed the development capabilities from the extensions, and now everything works fine except oddly the Labels in the DeviceActivityReport no longer show anything. They worked fine before, and the same label logic is working 100% fine inside my main app.
Anyone encounter this before?
Hello.
I'm building an iOS application that builds a framework named Design.framework using Xcode 16.1. When I launch my application on iOS 17.X, i get the following runtime error
dyld[47899]: Library not loaded: /System/Library/Frameworks/SwiftUICore.framework/SwiftUICore
Referenced from: <E625A246-E36B-351A-B077-CC38BAB5E07B> /Users/v/Library/Developer/Xcode/DerivedData/iScribd-bexojbdreldwkvbpzioqueldnvng/Build/Products/Debug_AppStore-iphonesimulator/Design.framework/Design
Reason: tried: '/Users/v/Library/Developer/Xcode/DerivedData/iScribd-bexojbdreldwkvbpzioqueldnvng/Build/Products/Debug_AppStore-watchsimulator/SwiftUICore.framework/SwiftUICore' (no such file), '/Users/v/Library/Developer/Xcode/DerivedData/iScribd-bexojbdreldwkvbpzioqueldnvng/Build/Products/Debug_AppStore-iphonesimulator/SwiftUICore.framework/SwiftUICore' (no such file), '/Users/v/Library/Developer/Xcode/DerivedData/iScribd-bexojbdreldwkvbpzioqueldnvng/Build/Products/Debug_AppStore-watchsimulator/PackageFrameworks/SwiftUICore.framework/SwiftUICore' (no such file), '/Users/v/Library/Developer/Xcode/DerivedData/iScribd-bexojbdreldwkvbpzioqueldnvng/Build/Products/Debug_AppStore-iphonesimulator/PackageFrameworks/SwiftUICore.framework/SwiftUICore' (no such file), '/Library/Developer/CoreSimulator/Volumes/iOS_21C62/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 17.2.simruntime/Contents/Resources/RuntimeRoot/System/Library/Frameworks/SwiftUICore.framework/SwiftUICore' (no such file), '/System/Library/Frameworks/SwiftUICore.framework/SwiftUICore' (no such file, not in dyld cache), '/Library/Developer/CoreSimulator/Volumes/iOS_21C62/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 17.2.simruntime/Contents/Resources/RuntimeRoot/System/Library/Frameworks/SwiftUICore.framework/SwiftUICore' (no such file)
This error does not happen on iOS 18+. When i run dyld_info Design.framework/Design, i see that there is indeed a dependency on SwiftUICore.framework
Design.framework/Design [arm64]:
-platform:
platform minOS sdk
iOS-simulator 16.0 18.1
-uuid:
09880F25-DC86-3D8E-BCAE-1A283508D879
-segments:
load-offset segment section sect-size seg-size max-prot init-prot
0x00000000 __TEXT 416KB r.x
0x00000000 __TEXT 416KB r.x
0x0000543C __text 355508
0x0005C0F0 __stubs 3168
0x0005CD50 __objc_methlist 32
0x0005CD70 __const 8296
0x0005EDD8 __swift5_typeref 15820
0x00062BB0 __cstring 6885
0x00064698 __constg_swiftt 2804
0x0006518C __swift5_builtin 40
0x000651C0 __swift5_reflstr 2952
0x00065D48 __swift5_assocty 816
0x00066078 __objc_methname 299
0x000661A4 __swift5_proto 368
0x00066314 __swift5_types 280
0x0006642C __swift5_fieldmd 3688
0x00067294 __swift5_protos 8
0x0006729C __swift5_capture 244
0x00067390 __unwind_info 2296
0x00067C88 __eh_frame 888
0x00068000 __DATA_CONST 16KB rw.
0x00068000 __DATA_CONST 16KB rw.
0x00068000 __got 3704
0x00068E78 __const 6864
0x0006A948 __objc_classlist 40
0x0006A970 __objc_imageinfo 8
0x0006C000 __DATA 32KB rw.
0x0006C000 __DATA 32KB rw.
0x0006C000 __objc_const 792
0x0006C318 __objc_selrefs 96
0x0006C378 __objc_classrefs 48
0x0006C3A8 __objc_data 208
0x0006C478 __data 4136
0x0006D4A0 __bss 12784
0x00070690 __common 4592
-linked_dylibs:
attributes load path
@rpath/CommonTools.framework/CommonTools
/System/Library/Frameworks/Foundation.framework/Foundation
/usr/lib/libobjc.A.dylib
/usr/lib/libSystem.B.dylib
/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation
/System/Library/Frameworks/CoreGraphics.framework/CoreGraphics
/System/Library/Frameworks/CoreText.framework/CoreText
weak-link /System/Library/Frameworks/DeveloperToolsSupport.framework/DeveloperToolsSupport
/System/Library/Frameworks/SwiftUI.framework/SwiftUI
/System/Library/Frameworks/SwiftUICore.framework/SwiftUICore
/System/Library/Frameworks/UIKit.framework/UIKit
/usr/lib/swift/libswiftCore.dylib
weak-link /usr/lib/swift/libswiftCoreAudio.dylib
/usr/lib/swift/libswiftCoreFoundation.dylib
weak-link /usr/lib/swift/libswiftCoreImage.dylib
weak-link /usr/lib/swift/libswiftCoreMedia.dylib
weak-link /usr/lib/swift/libswiftDarwin.dylib
weak-link /usr/lib/swift/libswiftDataDetection.dylib
weak-link /usr/lib/swift/libswiftDispatch.dylib
weak-link /usr/lib/swift/libswiftFileProvider.dylib
weak-link /usr/lib/swift/libswiftMetal.dylib
weak-link /usr/lib/swift/libswiftOSLog.dylib
/usr/lib/swift/libswiftObjectiveC.dylib
weak-link /usr/lib/swift/libswiftQuartzCore.dylib
weak-link /usr/lib/swift/libswiftSpatial.dylib
weak-link /usr/lib/swift/libswiftUniformTypeIdentifiers.dylib
weak-link /usr/lib/swift/libswiftXPC.dylib
/usr/lib/swift/libswift_Concurrency.dylib
weak-link /usr/lib/swift/libswiftos.dylib
weak-link /usr/lib/swift/libswiftsimd.dylib
weak-link /usr/lib/swift/libswiftUIKit.dylib
I can add a -weak_framework SwiftUICore to "Other Linker Flags" in my Design.framework Build Settings, and that will solve my problem, but I'd like to know what prompts my Design.framework to depend on SwiftUICore despite having a minimum set to iOS 16? And how am I supposed to handle devices prior to iOS 18 which do not have this library? is adding the linker flag the right way forward?
Topic:
UI Frameworks
SubTopic:
SwiftUI
Like many applications, mine involves navigation where the user starts a process on one screen and then progresses through several more steps to reach a conclusion. When he confirms that choice, I need to dismiss the entire stack. In my case, he's browsing contacts, selecting one, and then selecting a communication method from those offered by the contact.
This still appears to be a PITA in SwiftUI. NavigationPath is supposed to provide a way to programmatically control a stack of views. Well... I can't find a single example of how to use it for this, except with absurdly shallow (as in a single level) of child views that all take the same datatype.
Nowhere do I see how to use the path as users proceed through your view hierarchy with NavigationLinks. I have not seen any example of how elements get added to the path or how they are related to each added view. Nor can I find an example of popping views off the stack by removing related elements from the path.
I created a class that encloses a NavigationPath:
@Observable
class NavPathController
{
var path: NavigationPath
init()
{
path = NavigationPath()
}
func popOne()
{
path.removeLast()
}
func popAll()
{
path.removeLast(path.count)
}
}
In my root view, I pass a binding to this controller's NavigationPath when creating the NavigationStack:
@State private var viewStack = NavPathController()
var body: some View
{
NavigationStack(path: $viewStack.path)
{
VStack()
{
NavigationLink(destination: UserFindingView(viewPathController: viewStack), label: { Text("Pick a recipient") })
}
}
And likewise each view passes the same view-path controller object to each child view that's invoked with a NavigationLink (instead of using an environment variable, because I find those hokey). But in the end, the path is empty; not surprisingly, clearing it does not pop the views.
So how is one supposed to make this work?
Topic:
UI Frameworks
SubTopic:
SwiftUI
Using the new floating tab bar with ios18 on ipad with an RTL language, when the tabbar is correctly flipped and the right buttons become left buttons, the buttons are pushed off the screen on initial load but do come back after some navigating / reloading, have recreated in a fresh project.
When I present a view controller, whose view is a SwiftUI View, via presentAsModalWindow(_:) the presented window is no longer centered horizontally to the screen, but rather its origin is there. I know this issue occurs for macOS 15.2+, but can't tell if it is from 15.0+. I couldn't find any documentation on why was this changed.
Here's an example code that represents my architecture:
class RootViewController: NSViewController {
private lazy var button: NSButton = NSButton(
title: "Present",
target: self,
action: #selector(presentView))
override func viewDidLoad() {
super.viewDidLoad()
// Add button to tree
}
@objc func presentView() {
presentAsModalWindow(PresentedViewController())
}
}
class PresentedViewController: NSViewController {
override loadView() {
view = NSHostingView(rootView: MyView())
}
}
struct MyView: View {
/* impl */
}
Hi can you add caching to AsyncImage in the next swift revision
pls see image below.
without caching support it will redownload everything.
wasting api calls
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
}
}];
}
Hello,
is there a way to implement Continuity Markup in our own apps?
(This is what I'm talking about: https://support.apple.com/en-us/102269 , scroll down to "Use Continuity Markup").
Also, why does a QuickLook panel (QLPreviewPanel.shared()) not display the markup options when triggered from my app for png image files in my app's Group Container? Do I need to implement certain NSServicesMenuRequestor methods for that?
Sadly, I could not find any docs on that.
Thank you,
– Matthias
Hello, I have a Task model in my application which has an optional many to many relationship to a User model.
task.assignedUsers
user.tasks
I am looking to construct a SwiftData predicate to fetch tasks which either have no assigned users or assigned users does not contain specific user.
Here is a partially working predicate I have now:
static func assignedToOthersPredicate() -> Predicate<Task> {
let currentUserGUID = User.currentUserGUID
return #Predicate<Task> { task in
task.assignedUsers.flatMap { users in
users.contains(where: { $0.guid != currentUserGUID })
} == true
}
}
This only returns tasks assigned to others, but not those which have no assigned users.
If combine it with this:
static func notAssignedPredicate() -> Predicate<Task> {
return #Predicate<Task> { task in
task.assignedUsers == nil
}
}
Then I get a run time crash: "to-many key not allowed here"
What is the proper way to do this?
Thanks.
There's an easily reproducible SwiftUI bug on macOS where an app's UI state no longer updates/re-renders for "Designed for iPad" apps (i.e. ProcessInfo.processInfo.isiOSAppOnMac == true). The bug occurs in Xcode and also if the app is running independent of Xcode.
The bug occurs when:
the user Hides the app (i.e. it goes into the background)
the user puts the Mac to sleep (e.g. Apple menu > Sleep)
a total of ~60 seconds transpires (i.e. macOS puts the app into the "suspended state")
when the app is brought back into the foreground the UI no longer updates properly
The only way I have found to fix this is to manually open a new actual full app window via File > New, in which case the app works fine again in the new window.
The following extremely simple code in a default Xcode project illustrates the issue:
import SwiftUI
@main
struct staleApp: App {
@State private var isBright = true
var body: some Scene {
WindowGroup() {
ZStack {
(isBright ? Color.white : Color.black).ignoresSafeArea()
Button("TOGGLE") { isBright.toggle(); print("TAPPED") }
}
.onAppear { print("\(isBright ? "light" : "dark") view appeared") }
}
}
}
For the code above, after Hiding the app and putting the computer to sleep for 60 seconds or more, the button no longer swaps views, although the print statements still appear in the console upon tapping the button. Also, while in this buggy state, i can get the view to update to the current state (i.e. the view triggered by the last tap) by manually dragging the corner of the app window to resize the window. But after resizing, the view again does not update upon button tapping until I resize the window again.
so it appears the diff engine is mucked or that the Scene or WindowGroup are no longer correctly running on the main thread
I have tried rebuilding the entire view hierarchy by updating .id() on views but this approach does NOT work. I have tried many other options/hacks but have not been able to reset the 'view engine' other than opening a new window manually or by using: @Environment(.openWindow) private var openWindow
openWindow could be a viable solution except there's no way to programmatically close the old window for isiOSAppOnMac (@Environment(.dismissWindow) private var dismissWindow doesn't work for iOS)
Here is a simple main.swift file of a macOS app:
import SwiftUI
struct ContentView: View {
@State private var selectedItem = 0
@FocusState private var isListFocused: Bool
var body: some View {
List(0..<40, id: \.self, selection: $selectedItem) { index in
Text("\(index)")
.padding()
.focusable()
}
.focused($isListFocused)
.onAppear {
isListFocused = true
}
}
}
func createAppWindow() {
let window = NSWindow(
contentRect: .zero,
styleMask: [.titled],
backing: .buffered,
defer: false
)
window.contentViewController = NSHostingController(rootView: ContentView())
window.setContentSize(NSSize(width: 759, height: 300))
window.center()
window.makeKeyAndOrderFront(nil)
}
class AppDelegate: NSObject, NSApplicationDelegate {
func applicationDidFinishLaunching(_ notification: Notification) {
createAppWindow()
}
}
let delegate = AppDelegate()
NSApplication.shared.delegate = delegate
NSApplication.shared.run()
Try to move the focus with a keyboard slowly as shown on the GIF attached and you'll see that the focus items don't sit in a List's view.
I'm trying to combine a RotateGesture and a MagnifyGesture within a single SwiftUI view using SimultaneousGesture. My goal is to allow users to rotate and zoom an image (potentially at the same time). However, I’m running into a problem:
If only one gesture (say, the magnification) starts and finishes without triggering the other (rotation), it seems that the rotation gesture is considered "failed." After that, no further .onChanged or .onEnded callbacks fire for either gesture until the user lifts their fingers and starts over.
Here’s a simplified version of my code:
struct ImageDragView: View {
@State private var scale: CGFloat = 1.0
@State private var lastScale: CGFloat = 1.0
@State private var angle: Angle = .zero
@State private var lastAngle: Angle = .zero
var body: some View {
Image("Stickers3")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(height: 100)
.rotationEffect(angle, anchor: .center)
.scaleEffect(scale)
.gesture(combinedGesture)
}
var combinedGesture: some Gesture {
SimultaneousGesture(
RotateGesture(minimumAngleDelta: .degrees(8)),
MagnifyGesture()
)
.onChanged { combinedValue in
if let magnification = combinedValue.second?.magnification {
let minScale = 0.2
let maxScale = 5.0
let newScale = magnification * lastScale
scale = max(min(newScale, maxScale), minScale)
}
if let rotation = combinedValue.first?.rotation {
angle = rotation + lastAngle
}
}
.onEnded { _ in
lastScale = scale
lastAngle = angle
}
}
}
If I pinch and rotate together (or just rotate), both gestures work as expected.
But if I only pinch (or, sometimes, if the rotation amount doesn’t meet minimumAngleDelta), subsequent gestures don’t trigger the .onChanged or .onEnded callbacks anymore, as if the entire gesture sequence is canceled.
I found that setting minimumAngleDelta: .degrees(0) helps because then rotation almost never fails. But I’d like to understand why this happens and whether there’s a recommended way to handle the situation where one gesture might be recognized but not the other, without losing the gesture recognition session entirely.
Is there a known workaround or best practice for combining a pinch and rotate gesture where either one might occur independently, but we still want both gestures to remain active?
Any insights would be much appreciated!
In our application we have two usecases for a Hotkey/Shortcut identification API/method.
We have some predefined shortcuts that will ship with our MacOS application. They may or may not change dynamically, based on what the user has already set as shortcuts/hotkeys, and also to avoid any important system wide shortcuts that the user may or may not have changed.
We allow the user to customize the shortcuts/hotkeys in our application, so we want to show what shortcuts the user already has in use system-wide and across their OS experience.
This gives rise to the need for an API that lets us know which shortcut/hotkeys are currently being used by the user and also the current system wide OS shortcuts in use.
Please let me know if there are any APIs in AppKit or SwiftUI we can use for the above