I honestly thought I was getting somewhere with this, but alas, no. Every time I do anything in my List of ItemRows it jumps back to the top.
Here's the setup:
DataService.swift:
final class DataService {
	static let shared = DataService()
	private init() {}
	let coreData: CoreData = CoreData()
	let modelData: ModelData = ModelData()
}
ModelData.swift:
@Observable
class ModelData: ObservableObject {
	var allItems: [ItemDetails]
	var standardItems: [ItemDetails]
	var archivedItems: [ItemDetails]
	init() {
		allItems = []
		standardItems = []
		archivedItems = []
	}
	func getInitialData() {
		// Get all items, then split them into archived and non-archived sets, because you can't use `.filter` in a view...
		allItems = dataService.coreData.getAllItems()
		standardItems.append(contentsOf: allItems.filter { !$0.archived })
		archivedItems.append(contentsOf: allItems.filter { $0.archived })
	}
}
MainApp.swift:
// Get access to the data; this singleton is a global as non-view-based functions, including the `Scene`, need to access the model data
let dataService: DataService = DataService.shared
@main
struct MainApp: App {
	// Should this be @ObservedObject or @StateObject?
	@ObservedObject private var modelData: ModelData = dataService.modelData
	// I would use @StateObject if the line was...
	//@StateObject private var modelData: ModelData = ModelData()  // right?
	// But then I couldn't use modelData outside of the view hierarchy
	var body: some Scene {
		WindowGroup {
			ZStack {
				MainView()
					.environment(modelData)
			}
		}
		.onAppear {
			modelData.getInitialData()
		}
	}
}
MainView.swift:
struct MainView: View {
	@Environment(ModelData.self) private var modelData: ModelData
	var body: some View {
		...
		ForEach(modelData.standardItems) { item in
			ItemRow(item)
		}
		ForEach(modelData.archivedItems) { item in
			ItemRow(item)
		}
	}
}
ItemRow.swift:
struct ItemRow: View {
	@Environment(\.accessibilityDifferentiateWithoutColor) private var accessibilityDifferentiateWithoutColor
	var item: ItemDetails
	@State private var showDeleteConfirmation: Bool = false
	var body: some View {
		// Construct the row view
		// `accessibilityDifferentiateWithoutColor` is used within the row to change colours if DWC is enabled, e.g. use different symbols instead of different colours for button images.
		// Add the .leftSwipeButtons, .rightSwipeButtons, and .contextMenu
		// Add the .confirmationDialog for when I want to ask for confirmation before deleting an item
	}
}
Now, the problems:
- 
Swipe an item row, tap one of the buttons, e.g. edit, and the list refreshes and jumps back to the top. In the console I see: ItemRow: @self, @identity, _accessibilityDifferentiateWithoutColor changed.Why did accessibilityDifferentiateWithoutColor change? The setting in Settings > Accessibility > Display & Text Size has not been changed, so why does the row's view think it changed?
- 
With a .confirmationDialogattached to the end of theItemRow(as seen in the code above), if I swipe and tap the delete button the list refreshes and jumps back to the top again. In the console I see:ItemRow: @self, @identity, _accessibilityDifferentiateWithoutColor, _showDeleteConfirmation changed.Right, it changed for the one row that I tapped the button for. Why does every row get redrawn?
I already had to shift from using the colorScheme environment variable to add new asset colours with light and dark variants to cover this, but you can't do that with DWC.
Honestly, managing state in SwiftUI is a nightmare. I had zero problems until iOS 26 started removing one or two rows when I scrolled, and the fix for that - using @Statebject/@ObservedObject - has introduced multiple further annoying, mind-bending problems, and necessitated massive daily refactorings. And, of course, plenty of my time islost trying to figure out where a problem is in the code because "The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions"...
 
  
  
  
    
  
