Post

Replies

Boosts

Views

Activity

Reply to How to handle alert when deleting row from List
UPDATE: I believe I've found a fix. The issue was partly that the buttons I want in .swipeActions(edge: .leading) { ... } are in a separate View struct called LeftSwipeButtons, and the ones going into .swipeActions(edge: .trailing) { ... } are in their own struct called RightSwipeButtons. This means passing Binding vars into them so that the ItemRow can use them, and send their value back to the view that's got my List in it, i.e.: struct ItemRow: View { @Binding var x: Bool @Binding var y: Bool var body: some View { ... } .swipeActions(edge: .leading) { LeftSwipeButtons(x: $x, y: $y ... ) } .swipeActions(edge: .trailing) { RightSwipeButtons(x: $x, y: $y ... ) // Has .confirmationDialog inside // But also exhibits the issue if I put .confirmationDialog here } .contextMenu { ContextMenu( ... ) // Has .confirmationDialog inside // But also exhibits the issue if I put .confirmationDialog here } } Adding .confirmationDialog inside RightSwipeButtons or inside .swipeActions didn't work because the button disappeared. It seems that the fix for this was to move all that code back into the ItemRow itself and add .confirmationDialog onto the end. Same problem with the context menu. I couldn't add .confirmationDialog inside my ContextMenu struct, or add it inside .contextMenu. Once I moved all the code back into ItemRow it all worked (though ItemRow is now about 450 lines...). struct ItemRow: View { var body: some View { ... } .swipeActions(edge: .leading) { if(a == 1) { ... }. // etc. } .swipeActions(edge: .trailing) { if(b == 2) { ... }. // etc. } .contextMenu { ... } .confirmationDialog { ... } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Oct ’25
Reply to How to handle alert when deleting row from List
Okay, I've created new vars in the model data. The initial set of data is read from Core Data, which is then filtered into the standardItems var, and the archived ones go into archivedItems. The List now doesn't use .filter, it just uses the specific set of data as required. However, this did not fix the issue with the list refreshing when I tap the delete swipe button. I want to show an alert to ask for confirmation to delete an item before deleting it. I swipe the row to show the delete button. The moment I tap it, the list refreshes. This happens just because the @State var showAlert has been changed. The confirmation alert does appear, but the list is now at the top (again). Look at the code I added in the first post above. RightSwipeButtons has showAlert as a Binding var, which is why it changes in ItemListView. I can't use confirmationDialog(_:isPresented:titleVisibility:actions:message:) on the swipe button because the button disappears and the alert has nothing to anchor itself to. So, how do I do this? How does anyone do this? It seems every time I make a change to adhere to best practice, SwiftUI throws another obstacle in my way that takes a day or more to figure out - and a lot of refactoring.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Oct ’25
Reply to List jumps back to the top
I've spent the last three hours changing every instance of colorScheme == .dark ? Color1 : Color2 into asset colours, and this fixes the Dark Mode issue. All it seems you can do with @Environment(\.colorScheme) var colorScheme is read its value, but not do anything with it for fear it will redraw the entire view. And, when you use it in a view that's used in a List, your entire list will be redrawn. Anyway, that's fixed now. Thanks for your help.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Oct ’25
Reply to List jumps back to the top
Yes, I change the UI when colorScheme changes, otherwise what's the point of that environment variable? For example: RoundedRectangle(cornerRadius: 8) .shadow(color: (colorScheme == .dark ? Color.systemGray.opacity(0.6) : Color.systemGray3.opacity(0.9)), radius: 4, x: 0, y: 0) Is there some other way of doing this? If I create a new colour in Assets with a dark and light appearance to cover that use case, I would have to create tons of colours to cover every other use case, i.e.: .background(colorScheme == .dark ? Color.green : Color.white) .background(colorScheme == .dark ? Color.blue : Color.red) What is the reason that SwiftUI will redraw a view - and bounce you back to the top of a List of views - because Dark Mode was turned on? This is how modelData is created: // A global: let dataService: DataService = DataService.shared // The singleton: final class DataService { static let shared = DataService() private init() {} let coreData: CoreData = CoreData() let modelData: ModelData = ModelData() } The model initialiser does this: availableItems = [] filteredItems = [] mainItem = itemDetails.blankItem // Then the rest are settings that pull their values from defaults, such as: lastUpdated = defaultsGetLastUpdatedDate() It's a singleton, so when it's created at the app level, I call a method in the .onAppear {} of the app's WindowGroup: func getInitialModelData() { availableItems = dataService.coreData.getAllEvents() filteredItems(contentsOf: availableItems) mainItem = dataService.coreData.getMainItem() } That method is only ever called once. At no point when I turn on Dark Mode does anything happen in ModelData. These issues didn't happen before I switched to @StateObject.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Oct ’25
Reply to List jumps back to the top
Here's the code for creating an item in the List: fileprivate func drawItemRow(_ item: ItemDetails) -> some View { return ItemRow(item: item) .id(item.id) .swipeActions(edge: .leading) { LeftSwipeButtons(item: item) } .swipeActions(edge: .trailing, allowsFullSwipe: false) { RightSwipeButtons(item: item) } .contextMenu { ItemContextMenu(item: item) } } ... List { ForEach(modelData.filteredItems) { item in drawItemRow(item) } } .id(UUID()) struct itemRow: View { // @Environment(ModelData.self) private var modelData: ModelData @Environment(\.accessibilityDifferentiateWithoutColor) var accessibilityDifferentiateWithoutColor @Environment(\.colorScheme) var colorScheme var item: ItemDetails var body: some View { if(item.name == "TestItem") { let _ = Self._printChanges() } ... } } I added the _printChanges call for a specific row (so I can isolate it). On first displaying it, I get: ItemRow: @self, @identity, _accessibilityDifferentiateWithoutColor, _colorScheme changed. When I manually change to Dark Mode, I get this: ItemRow: @identity, _colorScheme changed. itemRow: @self, @identity, _accessibilityDifferentiateWithoutColor, _colorScheme changed. Right now I'm using the singleton for the modelData, i.e. dataService.modelData anywhere it's needed in the ItemRow struct, but if I uncomment @Environment(ModelData.self) private var modelData: ModelData (and use modelData) it says _modelData also changed. The model data did not change. If I also print out the Item.id that's used as the .id() on the row, it stays the same, so I'm not sure what @identity refers to. I don't get where I'm going wrong with this? Perhaps you can spot the obvious?
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Oct ’25
Reply to List jumps back to the top
I'm not sure either, @Claude31, but before I implemented the @StateObject for my model data this didn't happen. I understand that using @StateObject is the correct thing to do, but why does SwiftUI throw in these extra problems when you're doing things the right way?
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Oct ’25
Reply to List jumps back to the top
Thanks @Claude31, I have found stuff like that, yeah. For the section in my list that can be expanded and contracted, ScrollViewReader and .scrollTo work to keep you in the right place, so thanks for the hint. This is the code for the List, if it helps: ScrollViewReader { proxy in List { // Standard items ForEach(modelData.filteredItems.filter { !$0.archived }) { item in ItemRow(item) } // Archived items if(modelData.filteredItems.filter { $0.archived }.count > 0) { ListSectionHeader_Archived() .id("ListSectionHeader_Archived") .onTapGesture { modelData.archivedItemsExpanded.toggle() DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { proxy.scrollTo("ListSectionHeader_Archived") } } if(modelData.archivedItemsExpanded) { ForEach(modelData.filteredItems.filter { $0.archived }) { item in ItemRow(item) } } } } // List .id(UUID()) } I still can't figure out a way to stop the list from jumping back to the top when the device's Dark Mode setting changes. Why does SwiftUI think the data is different?
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Oct ’25
Reply to List rows disappearing when scrolling
Hi, thanks for the response. I've created a DataService singleton that keeps access to my Core Data store and the model data, which simplifies things a little. Anywhere I used to use coreData.shared.doSomething() I now use dataService.coreData.doSomething(), and modelData.getSomething() is now dataService.modelData.getSomething() etc., so thanks for that suggestion. I also now use a @StateObject for the model data at the App level and pass it through the view hierarchy with .environment(modelData), and it seems to work well. (I had already implemented .environment(modelData) before but it wasn't a @StateObject.) The disappearing rows issue is now fixed, thanks!
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Oct ’25
Reply to NVMe External Disk working in MacOS Sequoia But not in Tahoe
These are the Developer Forums, where third-party developers of apps for Apple's platforms ask each other for hints and tips on coding. These forums aren't a direct line to Apple's developers. If you have an issue, you can raise a bug at: https://feedbackassistant.apple.com/ If you do so, please provide the full model number for your NVMe drive, and the exact versions of macOS that you tried. They will be needed.
Topic: Community SubTopic: Apple Developers Tags:
Sep ’25
Reply to .tint() has no effect on macOS Liquid Glass toggles (on state background)
This page says: Some controls adapt to the tint color differently based on their style, the current platform, and the surrounding context. For example, in macOS, a button with the bordered style doesn’t tint its background, but one with the borderedProminent style does. In macOS, neither of these button styles tint their label, but they do in other platforms. Is it possible that Toggles also don't respect the .tint modifier on macOS? Does it work if you use different styles? If you think it's a bug, raise it in the usual way, at: https://feedbackassistant.apple.com/ then post the FB number here.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Sep ’25
Reply to How to handle alert when deleting row from List
UPDATE: I believe I've found a fix. The issue was partly that the buttons I want in .swipeActions(edge: .leading) { ... } are in a separate View struct called LeftSwipeButtons, and the ones going into .swipeActions(edge: .trailing) { ... } are in their own struct called RightSwipeButtons. This means passing Binding vars into them so that the ItemRow can use them, and send their value back to the view that's got my List in it, i.e.: struct ItemRow: View { @Binding var x: Bool @Binding var y: Bool var body: some View { ... } .swipeActions(edge: .leading) { LeftSwipeButtons(x: $x, y: $y ... ) } .swipeActions(edge: .trailing) { RightSwipeButtons(x: $x, y: $y ... ) // Has .confirmationDialog inside // But also exhibits the issue if I put .confirmationDialog here } .contextMenu { ContextMenu( ... ) // Has .confirmationDialog inside // But also exhibits the issue if I put .confirmationDialog here } } Adding .confirmationDialog inside RightSwipeButtons or inside .swipeActions didn't work because the button disappeared. It seems that the fix for this was to move all that code back into the ItemRow itself and add .confirmationDialog onto the end. Same problem with the context menu. I couldn't add .confirmationDialog inside my ContextMenu struct, or add it inside .contextMenu. Once I moved all the code back into ItemRow it all worked (though ItemRow is now about 450 lines...). struct ItemRow: View { var body: some View { ... } .swipeActions(edge: .leading) { if(a == 1) { ... }. // etc. } .swipeActions(edge: .trailing) { if(b == 2) { ... }. // etc. } .contextMenu { ... } .confirmationDialog { ... } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Oct ’25
Reply to How to handle alert when deleting row from List
Okay, I've created new vars in the model data. The initial set of data is read from Core Data, which is then filtered into the standardItems var, and the archived ones go into archivedItems. The List now doesn't use .filter, it just uses the specific set of data as required. However, this did not fix the issue with the list refreshing when I tap the delete swipe button. I want to show an alert to ask for confirmation to delete an item before deleting it. I swipe the row to show the delete button. The moment I tap it, the list refreshes. This happens just because the @State var showAlert has been changed. The confirmation alert does appear, but the list is now at the top (again). Look at the code I added in the first post above. RightSwipeButtons has showAlert as a Binding var, which is why it changes in ItemListView. I can't use confirmationDialog(_:isPresented:titleVisibility:actions:message:) on the swipe button because the button disappears and the alert has nothing to anchor itself to. So, how do I do this? How does anyone do this? It seems every time I make a change to adhere to best practice, SwiftUI throws another obstacle in my way that takes a day or more to figure out - and a lot of refactoring.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Oct ’25
Reply to List jumps back to the top
I've spent the last three hours changing every instance of colorScheme == .dark ? Color1 : Color2 into asset colours, and this fixes the Dark Mode issue. All it seems you can do with @Environment(\.colorScheme) var colorScheme is read its value, but not do anything with it for fear it will redraw the entire view. And, when you use it in a view that's used in a List, your entire list will be redrawn. Anyway, that's fixed now. Thanks for your help.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Oct ’25
Reply to List jumps back to the top
Yes, I change the UI when colorScheme changes, otherwise what's the point of that environment variable? For example: RoundedRectangle(cornerRadius: 8) .shadow(color: (colorScheme == .dark ? Color.systemGray.opacity(0.6) : Color.systemGray3.opacity(0.9)), radius: 4, x: 0, y: 0) Is there some other way of doing this? If I create a new colour in Assets with a dark and light appearance to cover that use case, I would have to create tons of colours to cover every other use case, i.e.: .background(colorScheme == .dark ? Color.green : Color.white) .background(colorScheme == .dark ? Color.blue : Color.red) What is the reason that SwiftUI will redraw a view - and bounce you back to the top of a List of views - because Dark Mode was turned on? This is how modelData is created: // A global: let dataService: DataService = DataService.shared // The singleton: final class DataService { static let shared = DataService() private init() {} let coreData: CoreData = CoreData() let modelData: ModelData = ModelData() } The model initialiser does this: availableItems = [] filteredItems = [] mainItem = itemDetails.blankItem // Then the rest are settings that pull their values from defaults, such as: lastUpdated = defaultsGetLastUpdatedDate() It's a singleton, so when it's created at the app level, I call a method in the .onAppear {} of the app's WindowGroup: func getInitialModelData() { availableItems = dataService.coreData.getAllEvents() filteredItems(contentsOf: availableItems) mainItem = dataService.coreData.getMainItem() } That method is only ever called once. At no point when I turn on Dark Mode does anything happen in ModelData. These issues didn't happen before I switched to @StateObject.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Oct ’25
Reply to List jumps back to the top
Here's the code for creating an item in the List: fileprivate func drawItemRow(_ item: ItemDetails) -> some View { return ItemRow(item: item) .id(item.id) .swipeActions(edge: .leading) { LeftSwipeButtons(item: item) } .swipeActions(edge: .trailing, allowsFullSwipe: false) { RightSwipeButtons(item: item) } .contextMenu { ItemContextMenu(item: item) } } ... List { ForEach(modelData.filteredItems) { item in drawItemRow(item) } } .id(UUID()) struct itemRow: View { // @Environment(ModelData.self) private var modelData: ModelData @Environment(\.accessibilityDifferentiateWithoutColor) var accessibilityDifferentiateWithoutColor @Environment(\.colorScheme) var colorScheme var item: ItemDetails var body: some View { if(item.name == "TestItem") { let _ = Self._printChanges() } ... } } I added the _printChanges call for a specific row (so I can isolate it). On first displaying it, I get: ItemRow: @self, @identity, _accessibilityDifferentiateWithoutColor, _colorScheme changed. When I manually change to Dark Mode, I get this: ItemRow: @identity, _colorScheme changed. itemRow: @self, @identity, _accessibilityDifferentiateWithoutColor, _colorScheme changed. Right now I'm using the singleton for the modelData, i.e. dataService.modelData anywhere it's needed in the ItemRow struct, but if I uncomment @Environment(ModelData.self) private var modelData: ModelData (and use modelData) it says _modelData also changed. The model data did not change. If I also print out the Item.id that's used as the .id() on the row, it stays the same, so I'm not sure what @identity refers to. I don't get where I'm going wrong with this? Perhaps you can spot the obvious?
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Oct ’25
Reply to List jumps back to the top
I'm not sure either, @Claude31, but before I implemented the @StateObject for my model data this didn't happen. I understand that using @StateObject is the correct thing to do, but why does SwiftUI throw in these extra problems when you're doing things the right way?
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Oct ’25
Reply to List jumps back to the top
Thanks @Claude31, I have found stuff like that, yeah. For the section in my list that can be expanded and contracted, ScrollViewReader and .scrollTo work to keep you in the right place, so thanks for the hint. This is the code for the List, if it helps: ScrollViewReader { proxy in List { // Standard items ForEach(modelData.filteredItems.filter { !$0.archived }) { item in ItemRow(item) } // Archived items if(modelData.filteredItems.filter { $0.archived }.count > 0) { ListSectionHeader_Archived() .id("ListSectionHeader_Archived") .onTapGesture { modelData.archivedItemsExpanded.toggle() DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { proxy.scrollTo("ListSectionHeader_Archived") } } if(modelData.archivedItemsExpanded) { ForEach(modelData.filteredItems.filter { $0.archived }) { item in ItemRow(item) } } } } // List .id(UUID()) } I still can't figure out a way to stop the list from jumping back to the top when the device's Dark Mode setting changes. Why does SwiftUI think the data is different?
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Oct ’25
Reply to List rows disappearing when scrolling
Hi, thanks for the response. I've created a DataService singleton that keeps access to my Core Data store and the model data, which simplifies things a little. Anywhere I used to use coreData.shared.doSomething() I now use dataService.coreData.doSomething(), and modelData.getSomething() is now dataService.modelData.getSomething() etc., so thanks for that suggestion. I also now use a @StateObject for the model data at the App level and pass it through the view hierarchy with .environment(modelData), and it seems to work well. (I had already implemented .environment(modelData) before but it wasn't a @StateObject.) The disappearing rows issue is now fixed, thanks!
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Oct ’25
Reply to 'tabViewBottomAccessory' leaves an empty accessory area when conditionally hidden
You should probably raise this as a bug in the usual way. It won't really get progressed if it's only posted in these Developer Forums. You need to raise each issue you find separately at https://feedbackassistant.apple.com/ You can post the FB numbers here if you want, so that others can link to them.
Topic: UI Frameworks SubTopic: SwiftUI
Replies
Boosts
Views
Activity
Oct ’25
Reply to SwiftUI's tabViewBottomAccessory API Cannot Control Visibility in iOS 26.1
You should probably raise this as a bug in the usual way. It won't really get progressed if it's only posted in these Developer Forums. You need to raise each issue you find separately at https://feedbackassistant.apple.com/ You can post the FB numbers here if you want, so that others can link to them.
Topic: UI Frameworks SubTopic: SwiftUI
Replies
Boosts
Views
Activity
Oct ’25
Reply to Zoom crashing in iOS 26.1
iOS 26.1 is in beta, and there are going to be issues. Zoom probably need to update their app to work properly in 26.1. Have you raised this issue with Zoom?
Replies
Boosts
Views
Activity
Oct ’25
Reply to app review asks for 3.5 inch iPhone screenshot
It depends. What version of iOS are you targeting as a minimum? What does App Store Connect require? If the app can be installed and used on a 3.5-inch device, and there are no screenshots for it (and you haven't told App Store Connect that it can use a larger size scaled down), then you have to provide them.
Replies
Boosts
Views
Activity
Sep ’25
Reply to NVMe External Disk working in MacOS Sequoia But not in Tahoe
These are the Developer Forums, where third-party developers of apps for Apple's platforms ask each other for hints and tips on coding. These forums aren't a direct line to Apple's developers. If you have an issue, you can raise a bug at: https://feedbackassistant.apple.com/ If you do so, please provide the full model number for your NVMe drive, and the exact versions of macOS that you tried. They will be needed.
Topic: Community SubTopic: Apple Developers Tags:
Replies
Boosts
Views
Activity
Sep ’25
Reply to tabViewBottomAccessory AttributeGraph cycles, broken behavior of views participating in cycles
I'm also getting this, and without a fix I cannot release an updated version of my app.
Topic: UI Frameworks SubTopic: SwiftUI
Replies
Boosts
Views
Activity
Sep ’25
Reply to .tint() has no effect on macOS Liquid Glass toggles (on state background)
This page says: Some controls adapt to the tint color differently based on their style, the current platform, and the surrounding context. For example, in macOS, a button with the bordered style doesn’t tint its background, but one with the borderedProminent style does. In macOS, neither of these button styles tint their label, but they do in other platforms. Is it possible that Toggles also don't respect the .tint modifier on macOS? Does it work if you use different styles? If you think it's a bug, raise it in the usual way, at: https://feedbackassistant.apple.com/ then post the FB number here.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Sep ’25