Please can somebody help me? I have a document-based iOS in the App Store (iNetWorth). I was able to run it on my M1 Mac Mini as a Mac (Designed for iPad) app without any issues until macOS 15. So, I created a simple test app based on a TabView to try and find out why I cannot get iNetWorth to run successfully on my Mac.
The issue is that when TabViewApp.swift file looks like this:
import SwiftUI
@main
struct TabViewApp: App {
var body: some Scene {
/*WindowGroup {
ContentView()
}*/
DocumentGroup(newDocument: TextFile()) { file in
ContentView(document: file.$document)
}
}
}
TabView fails to load the ContentView() - in Xcode 16.2 running on macOS 15.3.2. On opening, the TabView app prompts the user to open a new or existing file normally but it then opens a window that is empty, apart from a Documents button and a label displaying the filename with a dropdown menu (Duplicate, Move, Rename..., Export As…).
If the @Binding var document: TextFile line is removed from the ContentView() and the TabViewApp.swift file is changed to:
import SwiftUI
@main
struct TabViewApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
/*DocumentGroup(newDocument: TextFile()) { file in
ContentView(document: file.$document)
}*/
}
}
the TabView app loads and displays the ContentView() correctly.
Both versions of TabView, when running in Xcode on My Mac (Designed for iPad), produce these warnings:
CLIENT: Failure to determine if this machine is in the process of shutting down, err=1/Operation not permitted LSPrefs: could not find untranslocated node for <FSNode 0x6000013901a0> { isDir = ?, path = '/private/var/folders/3f/8788c4dj50q050_4wg9fssbr0000gp/X/518B55E1-0EC4-5D84-9202-4E44410EB249/d/Wrapper/TabView.app' }, proceeding on the assumption it is not translocated: Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted" LSPrefs: could not find untranslocated node for <FSNode 0x6000013901a0> { isDir = ?, path = '/private/var/folders/3f/8788c4dj50q050_4wg9fssbr0000gp/X/518B55E1-0EC4-5D84-9202-4E44410EB249/d/Wrapper/TabView.app' }, proceeding on the assumption it is not translocated: Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted" LSPrefs: could not find untranslocated node for <FSNode 0x6000013901a0> { isDir = ?, path = '/private/var/folders/3f/8788c4dj50q050_4wg9fssbr0000gp/X/518B55E1-0EC4-5D84-9202-4E44410EB249/d/Wrapper/TabView.app' }, proceeding on the assumption it is not translocated: Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted" LSPrefs: could not find untranslocated node for <FSNode 0x6000013901a0> { isDir = ?, path = '/private/var/folders/3f/8788c4dj50q050_4wg9fssbr0000gp/X/518B55E1-0EC4-5D84-9202-4E44410EB249/d/Wrapper/TabView.app' }, proceeding on the assumption it is not translocated: Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted”
However, the document-based version of TabView also displays these warnings:
cannot open file at line 49450 of [1b37c146ee] os_unix.c:49450: (2) open(/private/var/db/DetachedSignatures) - No such file or directory
I suspect that the lack of the DetachedSignatures file is the root cause of the ContentView() not being loaded but I cannot find out how to generate a DetachedSignatures file. Adding an empty DetachedSignatures file or directory to /private/var/db/ does not help.
Has anyone else experienced this problem (and maybe found a solution)? Should I raise it as a bug via Feedback or am I missing something obvious? Thanks!
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
Hello,
I am encountering an issue with .refreshable(action:) in ScrollView.
The refresh action works as expected when performing a pull-to-refresh. However, if I put the app in the background while the refresh operation is in progress, the refresh indicator remains visible on the screen when I return to the foreground and does not disappear.
Once I interact with the ScrollView after returning to the foreground, the refresh indicator disappears, and the functionality itself is not affected.
I initially attempted to resolve this issue by triggering a view redraw when scenePhase changes. However, since my app presents the SwiftUI view using UIHostingController, the scenePhase from the environment does not seem to function correctly.
This issue occurs on iOS 17.1 but does not appear on iOS 16.1.1.
Is there a known way to resolve this unexpected behavior?
Below is a simplified sample code (some parts are omitted):
struct MyView: View {
@StateObject private var model: MyModel
var body: some View {
ScrollView {
// My ContentViews...
}
.refreshable {
do {
try await self.model.refresh()
} catch {
// Handle error
}
}
}
}
@MainActor
final class MyModel: ObservableObject {
// === Some Code ===
func refresh() async throws {
let data = try await self.fetchData()
self.data = Array(OrderedSet(data))
}
}
I apologize for any mistakes in my English, as I am using a translation tool.
Thank you in advance for your help!
Best regards,
The behavior of the Button in ScrollView differs depending on how the View is displayed modally.
When the View is displayed as a .fullScreenCover, if the button is touched and scrolled without releasing the finger, the touch event is canceled and the action of the Button is not called.
On the other hand, if the View is displayed as a .sheet, the touch event is not canceled even if the view is scrolled without lifting the finger, and the action is called when the finger is released.
In order to prevent accidental interaction, I feel that the behavior of .fullScreenCover is better, as it cancels the event immediately when scrolling. Can I change the behavior of .sheet?
Demo movie is here:
https://x.com/kenmaz/status/1896498312737611891
Sample code
import SwiftUI
@main
struct SampleApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
struct ContentView: View {
@State private var showSheet = false
@State private var showFullScreen = false
var body: some View {
VStack(spacing: 16) {
Button("Sheet") {
showSheet.toggle()
}
Button("Full screen") {
showFullScreen.toggle()
}
}
.sheet(isPresented: $showSheet) {
SecondView()
}
.fullScreenCover(isPresented: $showFullScreen) {
SecondView()
}
.font(.title)
}
}
struct SecondView: View {
@Environment(\.dismiss) var dismiss
var body: some View {
ScrollView {
Button("Dismiss") {
dismiss()
}
.buttonStyle(MyButtonStyle())
.padding(.top, 128)
.font(.title)
}
}
}
private struct MyButtonStyle: ButtonStyle {
func makeBody(configuration: Self.Configuration) -> some View {
configuration
.label
.foregroundStyle(.red)
.background(configuration.isPressed ? .gray : .clear)
}
}
Topic:
UI Frameworks
SubTopic:
SwiftUI
I am working on a React Native application where I want to modify the native text selection menu (the menu that appears when you long-press on text). Specifically, I want to add a custom option alongside the default ones like Copy, Look Up, Translate, Search Web, and Share.
Is there a way to modify the native text selection menu inside a WebView on iOS?
How can I add a custom menu option to the default text selection menu while keeping all the default options intact?
I think it can be dismissed with dismiss() onInAppPurchaseCompletion action handler but I have no reason to handle it, and if it's not handled it will show error alerts for you (see documentation).
How can I dismiss it and still benefit from default onInAppPurchaseCompletion action?
Thanks,
In SwiftUI I want to create a list with LazyVstack and each row item in the LazyVstack is a LazyHstack of horizontally scrollable list of images with some description with line limit of 3 and width of every item is fixed to 100 but height of every item is variable as per description text content.
But in any of the rows if the first item has image description of 1 line and the remaining items in the same row has image description of 3 lines then the LazyHStack is truncating all the image descriptions in the same row to one line making all the items in that row of same height.
Why LazyHStack is not supporting items of varying height ?
Expected behaviour should be that height of every LazyHStack should automatically adjust as per item content height. But it seems SwiftUI is not supporting LazyHstack with items of varying height.
Will SwiftUI ever support this feature?
Topic:
UI Frameworks
SubTopic:
SwiftUI
Hi,
I have an existing Mac app on the App Store with a couple of widgets as part of the app. I want to now add a new widget to the WidgetBundle. When I build the updated app with Xcode, and then run the updated app, the widgets list doesn't seem to get updated in Notification Center or in the WidgetKit Simulator.
I do have the App Store version installed in the /Applications folder as well, so there might be some conflict. What's the trick to getting the widgets list to run the debug version?
I have an app which uses Scene
var body: some Scene {
WindowGroup {
RootView(root: appDelegate.root)
.edgesIgnoringSafeArea(.all)
.onOpenURL { url in
let stringUrl = url.absoluteString
if (stringUrl.starts(with: "http")) {
handleUniversalLink(url: stringUrl)
} else if (stringUrl.starts(with: "fb")) {
let _ = ApplicationDelegate.shared.application(
UIApplication.shared,
open: url,
sourceApplication: nil,
annotation: [UIApplication.OpenURLOptionsKey.annotation])
}
}
}
}
I need to detect when a user taps on status bar. And call some functions when he does it. Is it possible in Swift?
Topic:
UI Frameworks
SubTopic:
SwiftUI
I have DNG files that I want to open and show as EDR content in my app. It seems like the DNG files should have enough per pixel information to show more colors that Display P3 but whenever I load the images using CIRawFilter and then inspect the outputImage color space it is always "DisplayP3", not something like "ITU-R BT.2100 PQ" there doesn't seem to be any way to make it load with a different color space for displaying EDR images.
Does this make sense for DNG files, it seems like it should?
If I open the same file using CIImage with the expandToHDR option e.g.
CIImage(contentsOf: rawURL, options: [.expandToHDR: true])
then it does have the desired EDR color space, but then I don't get any of the properties that are available via the CIRAWFilter class to manipulate the data.
Basically I just want to be able to open the DNG file via CIRAWFilter and then display it in my SwiftUI app as an EDR image by adding the allowedDynamicRange(.high) property.
Image("my-dng-image").allowedDynamicRange(.high)
Or do DNG files (just RAW not ProRAW) not contain enough information to be displayed as EDR images, seems like they should.
This pertains to iPad apps and UITabbarController in UIKit.
Our internal app for employees utilizes UITabbarController displayed at the bottom of the screen. Users prefer to maintain consistency with it being at the bottom. It becomes challenging to argue against this when users point out the iPhone version displaying it "correctly" at the bottom. My response is to trust Apple's design team to keep it at the top.
One workaround is to develop the app using the previous Xcode version, version 15 (via Xcode Cloud), targeting padOS17. This ensures the tab bar is shown at the bottom of the screen. However, this approach has its drawbacks: Apple may not support it in the future, leading to missed secure updates for the app, among other issues.
Exploring the UITabbarController mode appears to be the solution I am seeking. To quote the documentation "on iPad, If the tabs array contains one or more UITabGroup items, the system displays the content as either a tab bar or a sidebar, depending on the context. Otherwise, it only displays the content only as a tab bar.". The part "displays the content only as a tab bar." made think this is BAU:
class ViewController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
self.mode = .tabBar
}
}
Unfortunately, this does not resolve the issue.
Is there an API method that can force the tabbar to its previous bottom position?
The app uses multiple windows. When we split a window to launch another instance, the tab bar appears at the bottom. This behavior seems tied to the form factor—or potentially to how many items are in the tab bar.
We could build a custom tab bar to override this, but that goes against my “don’t reinvent the wheel” principle.
Any comments we welcome and thank you for reading this (to the end)
Theo
TLDR: Applying a clipShape in a hoverEffect closure is preventing taps from getting through to buttons nested within an ornament.
I need to make a custom ornament menu, similar to the stock ornament available via TabView but with some visual tweaks. It displays icons, and then expands to display a label as the user hovers. Example:
I've put together a piece of sample code, following guidance from WWDC docs:
VStack {
}
.ornament(attachmentAnchor: .scene(.leading)) {
VStack {
ForEach(0...7, id:\.self) { index in
Button(action: {
print(index) // <---- This will not print
}) {
HStack {
Text("\(index)")
Text(" button")
}
}
}
}
.padding(12)
.glassBackgroundEffect()
.hoverEffect { effect, isActive, proxy in
effect
.clipShape(RoundedRectangle(cornerRadius: 36)
.size(width: isActive ? proxy.size.width : 72, height: proxy.size.height, anchor: .leading)
)
}
}
}
The buttons in this code cannot be interacted with, as the print statement never executes. What am I missing here? I've managed to get some weird behavior, sometimes a specific clipShape (like a circle) will allow a tap on a single button, but not others.
I wanted to perform simulation in my application as a self tour guide for my user. For this I want to programatically simulate various user interaction events like button click, keypress event in the UITextField or moving the cursor around in the textField. These are only few examples to state, it can be any user interaction event or other events.
I wanted to know what is the apple recommendation on how should these simulations be performed? Is there something that apple offers like creating an event which can be directly executed for simulations. Is there some library available for this purpose?
I'm implementing a custom text editor in SwiftUI using a UITextView wrapped in a UIViewRepresentable. The text editor works for basic text entry, but I'm encountering an issue with scrolling behavior.
When the UITextView becomes the first responder (when tapped), the parent ScrollView doesn't automatically scroll to make the text view visible. Instead, the scroll position jumps to the last known position (scrolls to a different text view that was previously focused).
Here's my implementation reduced to the minimum:
struct SpacedTextEditor: View {
@Binding var text: String
var body: some View {
MinimalEditor(text: $text)
}
}
private struct MinimalEditor: UIViewRepresentable {
@Binding var text: String
func makeUIView(context: Context) -> UITextView {
let textView = UITextView()
textView.backgroundColor = .clear
textView.delegate = context.coordinator
textView.isScrollEnabled = false
textView.text = text
return textView
}
func updateUIView(_ textView: UITextView, context _: Context) {
if textView.text != text {
textView.text = text
}
}
func makeCoordinator() -> Coordinator {
Coordinator(text: $text)
}
class Coordinator: NSObject, UITextViewDelegate {
var text: Binding<String>
init(text: Binding<String>) {
self.text = text
}
func textViewDidChange(_ textView: UITextView) {
text.wrappedValue = textView.text
}
}
}
The text editor is placed inside a ScrollView in my parent view. How can I ensure that when a user taps on the text editor, the ScrollView properly scrolls to make it fully visible or at least it doesn't jump to where the textfield is not even visible?
I need to use a custom textfield because I need to be able to modify the space between lines, and I didn't find a way to do this using the swiftUI component.
Topic:
UI Frameworks
SubTopic:
SwiftUI
Hello Apple Developer Community,
I’m experiencing an issue with my iOS app, "WaterReminder," where it builds successfully in Xcode 16.2 but crashes immediately upon launch in the iPhone 16 Pro Simulator running iOS 18.3.1. The crash is accompanied by a "Thread 1: signal SIGABRT" error, and the Xcode console logs indicate a dyld error related to XCTest.framework/XCTest not being loaded. I’ve tried several troubleshooting steps, but the issue persists, and I’d appreciate any guidance or insights from the community.
Here are the details:
Environment:
Xcode Version: 16.2
Simulator: iPhone 16 Pro, iOS 18.3.1
App: WaterReminder (written in SwiftUI 6)
Build Configuration: Debug
Issue Description:
The app builds without errors, but when I run it in the iPhone 16 Pro Simulator, it shows a white screen and crashes with a SIGABRT signal. The Xcode debugger highlights the issue in the main function or app delegate, and the console logs show the following error:
dyld[7358]: Library not loaded: @rpath/XCTest.framework/XCTest
Referenced from: <549B4D71-6B6A-314B-86BE-95035926310E> /Users/faytek/Library/Developer/CoreSimulator/Devices/2A51383F-D8EA-4750-AE22-4CDE745164CE/data/Containers/Bundle/Application/56D8B44F-6613-4756-89F0-CB33991F0821/WaterReminder.app/WaterReminder.debug.dylib
Reason: tried: '/Users/faytek/Library/Developer/Xcode/DerivedData/WaterReminder-cahqrulxghamvyclxaozotzrbsiz/Build/Products/Debug-iphonesimulator/XCTest.framework/XCTest' (no such file), '/Users/faytek/Library/Developer/CoreSimulator/Devices/2A51383F-D8EA-4750-AE22-4CDE745164CE/data/Containers/Bundle/Application/56D8B44F-6613-4756-89F0-CB33991F0821/WaterReminder.app/Frameworks/XCTest.framework/XCTest' (no such file), '/Users/faytek/Library/Developer/CoreSimulator/Devices/2A51383F-D8EA-4750-AE22-4CDE745164CE/data/Containers/Bundle/Application/56D8B44F-6613-4756-89F0-CB33991F0821/WaterReminder.app/XCTest.framework/XCTest' (no such file), '/Users/faytek/Library/Developer/CoreSimulator/Devices/2A51383F-D8EA-4750-AE22-4CDE745164CE/data/Containers/Bundle/Application/56D8B44F-6613-4756-89F0-CB33991F0821/WaterReminder.app/Frameworks/XCTest.framework/XCTest' (no such file), '/Users/faytek/Library/Developer/CoreSimulator/Devices/2A51383F-D8EA-4750-AE22-4CDE745164CE/data/Containers/Bundle/Application/56D8B44F-6613-4756-89F0-CB33991F0821/WaterReminder.app/XCTest.framework/XCTest' (no such file), '/Users/faytek/Library/Developer/CoreSimulator/Devices/2A51383F-D8EA-4750-AE22-4CDE745164CE/data/Containers/Bundle/Application/56D8B44F-6613-4756-89F0-CB33991F0821/WaterReminder.app/Frameworks/XCTest.framework/XCTest' (no such file), '/Library/Developer/CoreSimulator/Volumes/iOS_22D8075/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.3.simruntime/Contents/Resources/RuntimeRoot/System/Library/Frameworks/XCTest.framework/XCTest' (no such file)
What I’ve Tried:
◦ Verified that FBSnapshotTestCase is correctly added to the "Embed Frameworks" build phase.
◦ Confirmed that the Framework Search Paths in build settings point to the correct location.
◦ Ensured that all required frameworks are available in the dependencies folder.
◦ Cleaned the build folder (Shift + Option + Command + K) and rebuilt the project.
◦ Checked the target configuration to ensure XCTest.framework isn’t incorrectly linked to the main app target (it’s only in test targets).
◦ Updated Xcode and the iOS Simulator to the latest versions.
◦ Reset the simulator content and settings.
Despite these steps, the app continues to crash with the same dyld error and SIGABRT signal. I suspect there might be an issue with how XCTest.framework is being referenced or loaded in the simulator, possibly related to using SwiftUI 6, but I’m unsure how to resolve it.
Could anyone provide advice on why XCTest.framework is being referenced in my main app (since it’s not intentionally linked there) or suggest additional troubleshooting steps? I’d also appreciate any known issues or workarounds specific to Xcode 16.2, iOS 18.3.1, and SwiftUI 6.
Thank you in advance for your help!
Best regards,
Faycel
Hello!
I'm trying to set a UiRefreshControl.tintColor:
.onAppear {
UIRefreshControl.appearance().tintColor = UIColor.systemBlue
}
But instead of
I get
The color in the second picture is a high contrast version of the first one. I can't understand why it works this way.
I also tried the following.
UIRefreshControl.appearance().tintColor = UIColor(red: 0, green: 0.478, blue: 1, alpha: 1) // doesn't work
UIRefreshControl.appearance().tintColor = UIColor(named: "RefreshControlColor") // doesn't work, here set "High contrast" on and indicated Universal.systemBlueColor
Perhaps I missed something?
Hi everyone,
I believe this should be a simple and expected default behavior in a real-world app, but I’m unable to make it work:
1. I have a View (a screen/page in this case) that calls an endpoint using async/await.
2. If the endpoint hasn’t finished, but I navigate forward to a DetailView, I want the endpoint to continue fetching data (i.e., inside the @StateObject ViewModel that the View owns). This way, when I go back, the View will have refreshed with the fetched data once it completes.
3. If the endpoint hasn’t finished and I navigate back to the previous screen, I want it to be canceled, and the @StateObject ViewModel should be deinitialized.
I can achieve 1 and 3 using the .task modifier, since it automatically cancels the asynchronous task when the view disappears:
view
.task { await vm.getData() }
I can achieve 1 and 2 using a structured Task in the View (or in the ViewModel, its the same behavior), for example:
.onFirstAppearOnly {
Task { away vm.getData() }
}
onFirstAppearOnly is a custom modifier that I have for calling onAppear only once in view lifecycle. Just to clarify, dont think that part is important for the purpose of the example
But the question is: How can I achieve all three behaviors? Is this really such an unusual requirement?
My minimum deployment target is iOS 15, and I’m using NavigationView + NavigationLink. However, I have also tried using NavigationStack + NavigationPath and still couldn’t get it to work.
Any help would be much appreciated.
Thank you, folks!
I set UIToolbar and UIBarButtonItem to UITextField placed on Xib, but when I run it on iOS18 iPad, the following error is output to Xcode Console, and UIPickerView set to UITextField.inputView is not displayed.
Error: this application, or a library it uses, has passed an invalid numeric value (NaN, or not-a-number) to CoreGraphics API and this value is being ignored. Please fix this problem.
If you want to see the backtrace, please set CG_NUMERICS_SHOW_BACKTRACE environmental variable.
Backtrace:
<CGPathAddLineToPoint+71>
<+[UIBezierPath _continuousRoundedRectBezierPath:withRoundedCorners:cornerRadii:segments:smoothPillShapes:clampCornerRadii:]
<+[UIBezierPath _continuousRoundedRectBezierPath:withRoundedCorners:cornerRadius:segments:]+175>
<+[UIBezierPath _roundedRectBezierPath:withRoundedCorners:cornerRadius:segments:legacyCorners:]+338>
<-[_UITextMagnifiedLoupeView layoutSubviews]+2233>
<__56-[_UITextMagnifiedLoupeView _updateCloseLoupeAnimation:]_block_invoke+89>
<+[UIView(UIViewAnimationWithBlocksPrivate) _modifyAnimationsWithPreferredFrameRateRange:updateReason:animations:]+166>
<block_destroy_helper.269+92>
<block_destroy_helper.269+92>
<__swift_instantiateConcreteTypeFromMangledName+94289>
<block_destroy_helper.269+126>
<+[UIView(UIViewAnimationWithBlocks) _setupAnimationWithDuration:delay:view:options:factory:animations:start:anima
<block_destroy_helper.269+6763>
<block_destroy_helper.269+10907>
<-[_UITextMagnifiedLoupeView _updateCloseLoupeAnimation:]+389>
<-[_UITextMagnifiedLoupeView setVisible:animated:completion:]+256>
<-[UITextLoupeSession _invalidateAnimated:]+329>
<-[UITextRefinementTouchBehavior textLoupeInteraction:gestureChangedWithState:location:translation:velocity:
<-[UITextRefinementInteraction loupeGestureWithState:location:translation:velocity:modifierFlags:shouldCanc
<-[UITextRefinementInteraction loupeGesture:]+701>
<-[UIGestureRecognizerTarget _sendActionWithGestureRecognizer:]+71>
<_UIGestureRecognizerSendTargetActions+100>
<_UIGestureRecognizerSendActions+306>
<-[UIGestureRecognizer _updateGestureForActiveEvents]+704>
<_UIGestureEnvironmentUpdate+3892>
<-[UIGestureEnvironment _updateForEvent:window:]+847>
<-[UIWindow sendEvent:]+4937>
<-[UIApplication sendEvent:]+525>
<__dispatchPreprocessedEventFromEventQueue+1436>
<__processEventQueue+8610>
<updateCycleEntry+151>
<_UIUpdateSequenceRun+55>
<schedulerStepScheduledMainSection+165>
<runloopSourceCallback+68>
<__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__+17>
<__CFRunLoopDoSource0+157>
<__CFRunLoopDoSources0+293>
<__CFRunLoopRun+960>
<CFRunLoopRunSpecific+550>
<GSEventRunModal+137>
<-[UIApplication _run]+875>
<UIApplicationMain+123>
<__debug_main_executable_dylib_entry_point+63>
10d702478 204e57345
Type: Error | Timestamp: 2025-03-09 00:22:46.121407+09:00 | Process: FurusatoLocalCurrency | Library: CoreGraphics | Subsystem: com.apple.coregraphics | Category: Unknown process name | TID: 0x5c360
Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want.
Try this:
(1) look at each constraint and try to figure out which you don't expect;
(2) find the code that added the unwanted constraint or constraints and fix it.
(Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)
(
"<NSAutoresizingMaskLayoutConstraint:0x600002202a30 h=--& v=--& _UIToolbarContentView:0x7fc2c6a5b8f0.width == 0 (active)>",
"<NSLayoutConstraint:0x600002175e00 H:|-(0)-[_UIButtonBarStackView:0x7fc2c6817b10] (active, names: '|':_UIToolbarContentView:0x7fc2c6a5b8f0 )>",
"<NSLayoutConstraint:0x600002175e50 H:[_UIButtonBarStackView:0x7fc2c6817b10]-(0)-| (active, names: '|':_UIToolbarContentView:0x7fc2c6a5b8f0 )>",
"<NSLayoutConstraint:0x6000022019f0 'TB_Leading_Leading' H:|-(8)-[_UIModernBarButton:0x7fc2a5aa8920] (active, names: '|':_UIButtonBarButton:0x7fc2a5aa84d0 )>",
"<NSLayoutConstraint:0x600002201a40 'TB_Trailing_Trailing' H:[_UIModernBarButton:0x7fc2a5aa8920]-(0)-| (active, names: '|':_UIButtonBarButton:0x7fc2a5aa84d0 )>",
"<NSLayoutConstraint:0x600002201e50 'UISV-canvas-connection' UILayoutGuide:0x600003b7d420'UIViewLayoutMarginsGuide'.leading == _UIButtonBarButton:0x7fc2f57117f0.leading (active)>",
"<NSLayoutConstraint:0x600002201ea0 'UISV-canvas-connection' UILayoutGuide:0x600003b7d420'UIViewLayoutMarginsGuide'.trailing == UIView:0x7fc2a5aac8e0.trailing (active)>",
"<NSLayoutConstraint:0x6000022021c0 'UISV-spacing' H:[_UIButtonBarButton:0x7fc2f57117f0]-(0)-[UIView:0x7fc2a5aa8330] (active)>",
"<NSLayoutConstraint:0x600002202210 'UISV-spacing' H:[UIView:0x7fc2a5aa8330]-(0)-[_UIButtonBarButton:0x7fc2a5aa84d0] (active)>",
"<NSLayoutConstraint:0x600002202260 'UISV-spacing' H:[_UIButtonBarButton:0x7fc2a5aa84d0]-(0)-[UIView:0x7fc2a5aac8e0] (active)>",
"<NSLayoutConstraint:0x600002176f30 'UIView-leftMargin-guide-constraint' H:|-(0)-[UILayoutGuide:0x600003b7d420'UIViewLayoutMarginsGuide'](LTR) (active, names: '|':_UIButtonBarStackView:0x7fc2c6817b10 )>",
"<NSLayoutConstraint:0x600002176e40 'UIView-rightMargin-guide-constraint' H:[UILayoutGuide:0x600003b7d420'UIViewLayoutMarginsGuide']-(0)-|(LTR) (active, names: '|':_UIButtonBarStackView:0x7fc2c6817b10 )>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x600002201a40 'TB_Trailing_Trailing' H:[_UIModernBarButton:0x7fc2a5aa8920]-(0)-| (active, names: '|':_UIButtonBarButton:0x7fc2a5aa84d0 )>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.
I've encountered an issue where using @Observable in SwiftUI causes extra initializations and deinitializations when a reference type is included as a property inside a struct. Specifically, when I include a reference type (a simple class Empty {}) inside a struct (Test), DetailsViewModel is initialized and deinitialized twice instead of once. If I remove the reference type, the behavior is correct.
This issue does not occur when using @StateObject instead of @Observable. Additionally, I've submitted a feedback report: FB16631081.
Steps to Reproduce
Run the provided SwiftUI sample code (tested on iOS 18.2 & iOS 18.3 using Xcode 16.2).
Observe the console logs when navigating to DetailsView.
Comment out var empty = Empty() in the Test struct.
Run again and compare console logs.
Change @Observable in DetailsViewModel to @StateObject and observe that the issue no longer occurs.
Expected Behavior
The DetailsViewModel should initialize once and deinitialize once, regardless of whether Test contains a reference type.
Actual Behavior
With var empty = Empty() present, DetailsViewModel initializes and deinitializes twice. However, if the reference type is removed, or when using @StateObject, the behavior is correct (one initialization, one deinitialization).
Code Sample
import SwiftUI
enum Route {
case details
}
@MainActor
@Observable
final class NavigationManager {
var path = NavigationPath()
}
struct ContentView: View {
@State private var navigationManager = NavigationManager()
var body: some View {
NavigationStack(path: $navigationManager.path) {
HomeView()
.environment(navigationManager)
}
}
}
final class Empty { }
struct Test {
var empty = Empty() // Comment this out to make it work
}
struct HomeView: View {
private let test = Test()
@Environment(NavigationManager.self) private var navigationManager
var body: some View {
Form {
Button("Go To Details View") {
navigationManager.path.append(Route.details)
}
}
.navigationTitle("Home View")
.navigationDestination(for: Route.self) { route in
switch route {
case .details:
DetailsView()
.environment(navigationManager)
}
}
}
}
@MainActor
@Observable
final class DetailsViewModel {
var fullScreenItem: Item?
init() {
print("DetailsViewModel Init")
}
deinit {
print("DetailsViewModel Deinit")
}
}
struct Item: Identifiable {
let id = UUID()
let value: Int
}
struct DetailsView: View {
@State private var viewModel = DetailsViewModel()
@Environment(NavigationManager.self) private var navigationManager
var body: some View {
ZStack {
Color.green
Button("Show Full Screen Cover") {
viewModel.fullScreenItem = .init(value: 4)
}
}
.navigationTitle("Details View")
.fullScreenCover(item: $viewModel.fullScreenItem) { item in
NavigationStack {
FullScreenView(item: item)
.navigationTitle("Full Screen Item: \(item.value)")
.toolbar {
ToolbarItem(placement: .cancellationAction) {
Button("Cancel") {
withAnimation(completionCriteria: .logicallyComplete) {
viewModel.fullScreenItem = nil
} completion: {
var transaction = Transaction()
transaction.disablesAnimations = true
withTransaction(transaction) {
navigationManager.path.removeLast()
}
}
}
}
}
}
}
}
}
struct FullScreenView: View {
@Environment(\.dismiss) var dismiss
let item: Item
var body: some View {
ZStack {
Color.red
Text("Full Screen View \(item.value)")
.navigationTitle("Full Screen View")
}
}
}
Console Output
With var empty = Empty() in Test
DetailsViewModel Init
DetailsViewModel Init
DetailsViewModel Deinit
DetailsViewModel Deinit
Without var empty = Empty() in Test
DetailsViewModel Init
DetailsViewModel Deinit
Using @StateObject Instead of @Observable
DetailsViewModel Init
DetailsViewModel Deinit
Additional Notes
This issue occurs only when using @Observable. Switching to @StateObject prevents it. This behavior suggests a possible issue with how SwiftUI handles reference-type properties inside structs when using @Observable.
Using a struct-only approach (removing Empty class) avoids the issue, but that’s not always a practical solution.
Questions for Discussion
Is this expected behavior with @Observable?
Could this be an unintended side effect of SwiftUI’s state management?
Are there any recommended workarounds apart from switching to @StateObject?
Would love to hear if anyone else has run into this or if Apple has provided any guidance!
Hi everyone,
frome time to time I see crash which Im not able to debug, because there is no line of my code where crash occured.
This is a crash log what Im getting from time to time of some users. In my device I never get this kind of crash.
0 libswiftCore.dylib 0x1172c _assertionFailure(_:_:flags:) + 208
1 libswiftCore.dylib 0x198624 KEY_TYPE_OF_DICTIONARY_VIOLATES_HASHABLE_REQUIREMENTS(_:) + 2980
2 libswiftCore.dylib 0xdb6c8 specialized _NativeDictionary.uncheckedRemove(at:isUnique:) + 534
3 libswiftCore.dylib 0xb250c Dictionary._Variant.setValue(_:forKey:) + 204
4 libswiftCore.dylib 0x5a620 Dictionary.subscript.setter + 520
5 SwiftUICore 0xf62ec ForEachState.item(at:offset:) + 4340
6 SwiftUICore 0xf5054 ForEachState.forEachItem(from:style:do:) + 1796
7 SwiftUICore 0x2272f8 ForEachState.traitKeys.getter + 84
8 SwiftUICore 0x227298 ForEachList.traitKeys.getter + 24
9 SwiftUICore 0x227008 protocol witness for ViewList.traitKeys.getter in conformance SubgraphList + 76
10 SwiftUICore 0x227008 protocol witness for ViewList.traitKeys.getter in conformance SubgraphList + 76
11 SwiftUICore 0x227008 protocol witness for ViewList.traitKeys.getter in conformance SubgraphList + 76
12 SwiftUICore 0x227008 protocol witness for ViewList.traitKeys.getter in conformance SubgraphList + 76
13 SwiftUICore 0x2271fc DynamicViewList.WrappedList.traitKeys.getter + 88
27 SwiftUICore 0x226d18 specialized static SectionAccumulator.processUnsectionedContent(list:contentSubgraph:) + 84
28 SwiftUI 0x26afe0 ListSectionInfo.init(list:listAttribute:contentSubgraph:) + 132
29 SwiftUI 0x269bb0 UpdateCollectionViewListCoordinator.updateValue() + 1528
30 SwiftUI 0x785d4 partial apply for implicit closure #1 in closure #1 in closure #1 in Attribute.init<A>(_:) + 32
31 AttributeGraph 0xccac AG::Graph::UpdateStack::update() + 540
32 AttributeGraph 0xc870 AG::Graph::update_attribute(AG::data::ptr<AG::Node>, unsigned int) + 424
33 AttributeGraph 0xc444 AG::Subgraph::update(unsigned int) + 848
34 SwiftUICore 0x805a8 GraphHost.flushTransactions() + 860
35 SwiftUI 0x1ac84 closure #1 in _UIHostingView._renderForTest(interval:) + 24
36 SwiftUICore 0x7ffa8 partial apply for closure #1 in ViewGraphDelegate.updateGraph<A>(body:) + 28
37 SwiftUICore 0x7fd6c ViewRendererHost.updateViewGraph<A>(body:) + 120
38 SwiftUICore 0x7fce8 ViewGraphDelegate.updateGraph<A>(body:) + 84
39 SwiftUI 0x3e688 closure #1 in closure #1 in closure #1 in _UIHostingView.beginTransaction() + 172
40 SwiftUI 0x3e5d4 partial apply for closure #1 in closure #1 in closure #1 in _UIHostingView.beginTransaction() + 24
41 SwiftUICore 0x79720 closure #1 in static Update.ensure<A>(_:) + 56
42 SwiftUICore 0x796a4 static Update.ensure<A>(_:) + 100
43 SwiftUI 0x9c808 partial apply for closure #1 in closure #1 in _UIHostingView.beginTransaction() + 80
44 SwiftUICore 0x7f5e0 thunk for @callee_guaranteed () -> () + 28
45 SwiftUICore 0x6161c specialized closure #1 in static NSRunLoop.addObserver(_:) + 144
46 CoreFoundation 0x218a4 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 36
47 CoreFoundation 0x213f8 __CFRunLoopDoObservers + 552
48 CoreFoundation 0x75da8 __CFRunLoopRun + 948
49 CoreFoundation 0xc8284 CFRunLoopRunSpecific + 588
50 GraphicsServices 0x14c0 GSEventRunModal + 164
51 UIKitCore 0x3ee674 -[UIApplication _run] + 816
52 UIKitCore 0x14e88 UIApplicationMain + 340
53 SwiftUI 0x291ef8 closure #1 in KitRendererCommon(_:) + 168
54 SwiftUI 0x291e28 runApp<A>(_:) + 100
55 SwiftUI 0x291d0c static App.main() + 180
56 DholRainbow 0x3019e8 main + 4339145192 (DholRainbowApp.swift:4339145192)
57 ??? 0x1b0bf5de8 (Missing)
From Crashlytics I know at least human readable format of this error
Fatal error: Duplicate keys of type 'Contact' were found in a Dictionary. This usually means either that the type violates Hashable's requirements, or that members of such a dictionary were mutated after insertion.
I 've checked all my parts of code where Im using dictionary. This is a function which creating that particulary dictionary.
private func logsByDate() {
let groupedByDate = Dictionary(grouping: logs.filter { ($0.remoteParty as? Contact != nil) } ) {
$0.date.removeTimeStamp ?? .distantPast }.mapValues {
$0.compactMap { $0 }
}
var dayLogs = [DayLog]()
for date in groupedByDate {
var contacts = [CallLogContact]()
for log in logs.filter({ $0.date.removeTimeStamp ?? .distantPast == date.key }) {
if let contact = log.remoteParty as? Contact {
if contacts.firstIndex(where: {$0.contact == contact }) == nil {
let contactDayLogs = logs.filter({ $0.remoteParty as? Contact == contact && $0.date.removeTimeStamp == date.key})
contacts.append(
CallLogContact(
contact: contact,
logs: contactDayLogs,
lastCallLogDate: contactDayLogs.sorted(by: {$0.date > $1.date}).first?.date ?? .distantPast
)
)
}
}
}
dayLogs.append(DayLog(date: date.key, contact: contacts))
}
DispatchQueue.main.async {
self.groupedCallLogs = dayLogs
}
}
This function is called from 3 others functions based on notification from the server in case of new call log, fetched call logs and removed call logs.
In my collection view I have allowsSelection, allowsSelectionDuringEditing, and allowsMultipleSelectionDuringEditing set to true.
In my delegate's collectionView(_:shouldBeginMultipleSelectionInteractionAt:) I return true unconditionally, getting me the desired behavior of triggering edit mode with a two-finger swipe. So far so good.
The problem is that collectionView(_:shouldBeginMultipleSelectionInteractionAt:) is also called on a single-finger click from a trackpad. Tapping one of my cells is supposed to open a sub-screen, so with this happening there's no way to navigate my screen using a trackpad. This also goes against the documentation, which says this delegate method is supposed to get called because of a two-finger swipe.
Is there a way to keep that call from happing from a trackpad click? Or a way to distinguish whether I'm getting the call because of an actual two finger swipe?