Post

Replies

Boosts

Views

Activity

Reply to iOS18 beta2: NavigationStack, Views Being Popped Automatically
Out of curiosity, have you tried using the Observable macro instead of the older ObservableObject? Thank you for your response. Using Observation, this issue no longer occurs. Since this problem does not occur in iOS 17.x, it seems to be an issue with iOS 18.0 beta 2. Additionally, as our product code needs to support iOS 15 and later, replacing Observation—which is only available from iOS 17—with Model and View code would lead to considerable duplication and make it difficult. I also want to share that I was able to reproduce the issue with the following code, which does not use ObservableObject or Observation. import SwiftUI enum Kind { case none, a, b, c } // Selection is storing the selected values in the NavigationStack. struct Selection: Hashable, Identifiable { let id = UUID() let num: Int init(num: Int) { self.num = num print("id: \(id), num: \(num)") } } // Data is corresponding to the selection. struct Data { let data: Int } @main struct iOS16_4NavigationSampleApp: App { var body: some Scene { WindowGroup { RootView() } } } struct RootView: View { var body: some View { if #available(iOS 16.0, *) { NavigationStack { NavigationLink { ContentView() } label: { Text("album") } } } else { EmptyView() } } } struct ContentView: View { @State var kind: Kind = .a @State var vals: [Selection] = { return (1...5).map { Selection(num: $0) } }() @State var selection: Selection? @Environment(\.dismiss) private var dismiss var body: some View { list .onChange(of: self.selection) { newValue in print("changed: \(String(describing: newValue?.num))") } } @ViewBuilder private var list: some View { if #available(iOS 16.0, *) { List(selection: $selection) { ForEach(self.vals) { val in NavigationLink(value: val) { Text("\(String(describing: val))") } } } .navigationDestination(isPresented: .init(get: { return selection != nil }, set: { newValue in if !newValue { selection = nil } }), destination: { SubView(kind: .a) }) } } } // struct SubView: View { init(kind: Kind) { } init() { } var body: some View { Text("Content") } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jun ’24
Reply to Are changes to published embedded objects really not detected in SwiftUI?
How about trying this? @MainActor class UserManager: ObservableObject { @Published var user: User private var cancelSet: Set<AnyCancellable> = .init() init() { self.user = User() self.user.objectWillChange.sink { [weak self] in self?.objectWillChange.send() } .store(in: &cancelSet) Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { _ in Task { @MainActor in self.user.ID += "1" } } } } struct ContentView: View { @ObservedObject var userManager: UserManager var body: some View { VStack { Text("\(userManager.user.ID)") } .padding() } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jan ’24
Reply to App Freezes with AVPlayer Inside NavigationStack on iOS 17.2 beta
Update: I have tested on both the iPad Simulator and an actual iPad device. iPad Simulator (iPadOS 17.2 (21C5029e)): The issue occurs iPad real device (iPadOS 17.2 (21C5029g)): The issue does not occur I haven't been able to confirm on an actual iPhone, but it might be an issue that occurs only on the Simulator. It may be related to the thread below. Simulator crashing with iOS < 14. Started happening since Big Sur https://developer.apple.com/forums/thread/667921?page=2
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Nov ’23
Reply to When using keyboardShortcut, instance of StateObject is not deinitialized
Upon further investigation, I believe there's a high possibility that this is a bug. In the code below, model2 is not referenced by Button.action, yet deinit is not called for model2 just like for model. struct ContentView: View { @StateObject var model = Model() @StateObject var model2 = Model2() var body: some View { VStack { Button("Toggle") { model.flag.toggle() } .keyboardShortcut(.space, modifiers: []) } .padding() } } @MainActor class Model: ObservableObject{ @Published var flag: Bool = false init() { print("Model.init") } deinit { print("Model.deinit") } } @MainActor class Model2: ObservableObject{ @Published var flag: Bool = false init() { print("Model2.init") } deinit { print("Model2.deinit") } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Oct ’23
Reply to Infinite Loop Issue with View's onAppear and onDisappear in iOS 17 Beta
In my app, the above workaround caused another problem. But, I could avoid it by changing the next code using DispatchQueue.main.async. I hope this issue will be resolved by the public release of iOS 17. struct SampleSection: View { @State private var isLoaded = false var body: some View { let _ = Self._printChanges() Group { if !isLoaded { Section("Header") {} .hidden() } else { Section("Header") { Text("Text") } } } .onAppear { DispatchQueue.main.async { // or Task { @MainActor in NSLog("SampleSection onAppear.") isLoaded = true } } .onDisappear() { DispatchQueue.main.async { // or Task { @MainActor in NSLog("Sample Section onDisappear.") isLoaded = false } } } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jul ’23
Reply to Infinite Loop Issue with View's onAppear and onDisappear in iOS 17 Beta
Here is a workaround for this issue in the reproduction code. struct SampleSection: View { @State private var isLoaded = false var body: some View { let _ = Self._printChanges() if !isLoaded { Section("Header") {} .hidden() .onAppear { NSLog("SampleSection onAppear.") isLoaded = true } } else { Section("Header") { Text("Text") } .onDisappear() { NSLog("Sample Section onDisappear.") isLoaded = false } } } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jul ’23
Reply to iOS 16.4 NavigationStack Behavior Unstable
After modifying the ContentView as shown below, the transition to the SubView now works. (🌟 indicates the modified parts) However, since the cause of the issue is unknown, I cannot judge whether this is an appropriate workaround or not. struct ContentView: View { @StateObject private var model = ContentModel() @State private var selectedData: Value? // 🌟 @State private var isShowingSubView = false @Environment(\.dismiss) private var dismiss init() { } var body: some View { List(selection: $selectedData) { ForEach(model.vals) { val in NavigationLink(value: val) { Text("\(val.num)") } } } // 🌟 .onChange(of: selectedData, perform: { newValue in // In production code, convert data here. isShowingSubView = newValue != nil }) .navigationDestination(isPresented: $isShowingSubView, destination: { SubView(kind: model.kind) // SubView() }) .onChange(of: isShowingSubView) { newValue in if !newValue && selectedData != nil { selectedData = nil } } } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Apr ’23
Reply to iOS18 beta2: NavigationStack, Views Being Popped Automatically
Out of curiosity, have you tried using the Observable macro instead of the older ObservableObject? Thank you for your response. Using Observation, this issue no longer occurs. Since this problem does not occur in iOS 17.x, it seems to be an issue with iOS 18.0 beta 2. Additionally, as our product code needs to support iOS 15 and later, replacing Observation—which is only available from iOS 17—with Model and View code would lead to considerable duplication and make it difficult. I also want to share that I was able to reproduce the issue with the following code, which does not use ObservableObject or Observation. import SwiftUI enum Kind { case none, a, b, c } // Selection is storing the selected values in the NavigationStack. struct Selection: Hashable, Identifiable { let id = UUID() let num: Int init(num: Int) { self.num = num print("id: \(id), num: \(num)") } } // Data is corresponding to the selection. struct Data { let data: Int } @main struct iOS16_4NavigationSampleApp: App { var body: some Scene { WindowGroup { RootView() } } } struct RootView: View { var body: some View { if #available(iOS 16.0, *) { NavigationStack { NavigationLink { ContentView() } label: { Text("album") } } } else { EmptyView() } } } struct ContentView: View { @State var kind: Kind = .a @State var vals: [Selection] = { return (1...5).map { Selection(num: $0) } }() @State var selection: Selection? @Environment(\.dismiss) private var dismiss var body: some View { list .onChange(of: self.selection) { newValue in print("changed: \(String(describing: newValue?.num))") } } @ViewBuilder private var list: some View { if #available(iOS 16.0, *) { List(selection: $selection) { ForEach(self.vals) { val in NavigationLink(value: val) { Text("\(String(describing: val))") } } } .navigationDestination(isPresented: .init(get: { return selection != nil }, set: { newValue in if !newValue { selection = nil } }), destination: { SubView(kind: .a) }) } } } // struct SubView: View { init(kind: Kind) { } init() { } var body: some View { Text("Content") } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Jun ’24
Reply to iOS18 beta2: NavigationStack, Views Being Popped Automatically
I have posted FB14055676
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Jun ’24
Reply to App Only Crashes on Launch in iOS 17.4 for Production Version
This issue is likely caused by the following problem with Firebase. Apologies for suspecting StoreKit2. Release note: v10.22.0 Related: https://firebase.google.com/support/release-notes/ios#version_10220_-_march_4_2024 https://github.com/firebase/firebase-ios-sdk/issues/11403
Topic: App & System Services SubTopic: StoreKit Tags:
Replies
Boosts
Views
Activity
Mar ’24
Reply to Are changes to published embedded objects really not detected in SwiftUI?
How about trying this? @MainActor class UserManager: ObservableObject { @Published var user: User private var cancelSet: Set<AnyCancellable> = .init() init() { self.user = User() self.user.objectWillChange.sink { [weak self] in self?.objectWillChange.send() } .store(in: &cancelSet) Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { _ in Task { @MainActor in self.user.ID += "1" } } } } struct ContentView: View { @ObservedObject var userManager: UserManager var body: some View { VStack { Text("\(userManager.user.ID)") } .padding() } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Jan ’24
Reply to How to Retrieve the Previous Price of an AutoRenewable Subscription Product in StoreKit2?
Update. It seems that Transaction.price from iOS 17.2 can be used to get applied price. https://developer.apple.com/documentation/ios-ipados-release-notes/ios-ipados-17_2-release-notes#StoreKit https://developer.apple.com/documentation/storekit/transaction/4312704-price
Topic: App & System Services SubTopic: StoreKit Tags:
Replies
Boosts
Views
Activity
Dec ’23
Reply to App Freezes with AVPlayer Inside NavigationStack on iOS 17.2 beta
Update: I have tested on both the iPad Simulator and an actual iPad device. iPad Simulator (iPadOS 17.2 (21C5029e)): The issue occurs iPad real device (iPadOS 17.2 (21C5029g)): The issue does not occur I haven't been able to confirm on an actual iPhone, but it might be an issue that occurs only on the Simulator. It may be related to the thread below. Simulator crashing with iOS < 14. Started happening since Big Sur https://developer.apple.com/forums/thread/667921?page=2
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Nov ’23
Reply to FocusState not working as expected in iOS 17(Public Beta)
It seems that this issue was fixed in iOS 17.1(21B74)
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Oct ’23
Reply to When using keyboardShortcut, instance of StateObject is not deinitialized
Upon further investigation, I believe there's a high possibility that this is a bug. In the code below, model2 is not referenced by Button.action, yet deinit is not called for model2 just like for model. struct ContentView: View { @StateObject var model = Model() @StateObject var model2 = Model2() var body: some View { VStack { Button("Toggle") { model.flag.toggle() } .keyboardShortcut(.space, modifiers: []) } .padding() } } @MainActor class Model: ObservableObject{ @Published var flag: Bool = false init() { print("Model.init") } deinit { print("Model.deinit") } } @MainActor class Model2: ObservableObject{ @Published var flag: Bool = false init() { print("Model2.init") } deinit { print("Model2.deinit") } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Oct ’23
Reply to FocusState not working as expected in iOS 17(Public Beta)
I posted FB13169518
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Sep ’23
Reply to FocusState not working as expected in iOS 17(Public Beta)
I have found the simplest workaround for this code: use NavigationView {}.navigationViewStyle(.stack) instead of NavigationStack. However, using NavigationView may introduce other issues.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Sep ’23
Reply to iOS 17β SwiftUI: Differences in BottomBar Button Layout Between iOS 16 and Earlier, and iOS 17
I've posted FB12586646
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Jul ’23
Reply to Infinite Loop Issue with View's onAppear and onDisappear in iOS 17 Beta
In my app, the above workaround caused another problem. But, I could avoid it by changing the next code using DispatchQueue.main.async. I hope this issue will be resolved by the public release of iOS 17. struct SampleSection: View { @State private var isLoaded = false var body: some View { let _ = Self._printChanges() Group { if !isLoaded { Section("Header") {} .hidden() } else { Section("Header") { Text("Text") } } } .onAppear { DispatchQueue.main.async { // or Task { @MainActor in NSLog("SampleSection onAppear.") isLoaded = true } } .onDisappear() { DispatchQueue.main.async { // or Task { @MainActor in NSLog("Sample Section onDisappear.") isLoaded = false } } } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Jul ’23
Reply to Infinite Loop Issue with View's onAppear and onDisappear in iOS 17 Beta
Here is a workaround for this issue in the reproduction code. struct SampleSection: View { @State private var isLoaded = false var body: some View { let _ = Self._printChanges() if !isLoaded { Section("Header") {} .hidden() .onAppear { NSLog("SampleSection onAppear.") isLoaded = true } } else { Section("Header") { Text("Text") } .onDisappear() { NSLog("Sample Section onDisappear.") isLoaded = false } } } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Jul ’23
Reply to Infinite Loop Issue with View's onAppear and onDisappear in iOS 17 Beta
I've posted feedback. FB12552709
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Jul ’23
Reply to iOS 16.4 NavigationStack Behavior Unstable
After modifying the ContentView as shown below, the transition to the SubView now works. (🌟 indicates the modified parts) However, since the cause of the issue is unknown, I cannot judge whether this is an appropriate workaround or not. struct ContentView: View { @StateObject private var model = ContentModel() @State private var selectedData: Value? // 🌟 @State private var isShowingSubView = false @Environment(\.dismiss) private var dismiss init() { } var body: some View { List(selection: $selectedData) { ForEach(model.vals) { val in NavigationLink(value: val) { Text("\(val.num)") } } } // 🌟 .onChange(of: selectedData, perform: { newValue in // In production code, convert data here. isShowingSubView = newValue != nil }) .navigationDestination(isPresented: $isShowingSubView, destination: { SubView(kind: model.kind) // SubView() }) .onChange(of: isShowingSubView) { newValue in if !newValue && selectedData != nil { selectedData = nil } } } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Apr ’23