|
I struggle with @EnvironmentObject and passing Array-Elements to a SubView. For example:
Here are my questions:
I hope my problems are understandable. I really tried hours of solving especially the Nico |
|
hi, i've been following this variation of the same thread for a long time, and it took some time to get my head around the deletion situation as well. so i used the following (very slight) modification of your code, since what you posted was not making sense in XCode 11.5 (perhaps it does in XCode 12).
this should work fine for you as i think you want it to work. note that the
this might be the hardest thing to explain, and i am not sure that what i'll say here makes real sense. the ContentView is "on screen" when you delete something; when the @Published property wrapper triggers upon a deletion, SwiftUI tries to compare what it has with what it should be. what it has is 3 subviews (in my example) which have probably already been destroyed, so it reinstantiates the subviews without drawing (pre-deletion) to compare what it had with what will be shown next (post-deletion). the problem is that when it re-instantiates the View structs it had (i think it uses the body property to figure out what to draw, but never really draws them, so never calls the .onAppear modifier), unfortunately, one of them won't be able to recreate the index because you just deleted an item from the model previously referred to, so firstIndex will crash. this might be a tortured explanation -- serious readers, please jump in here -- but there's an easy way around it in the code i showed above. instantiation of a Subview struct will never try to compute an index, or use the item directly, until the
the code above bypasses this problem; and, frankly, you don't want a @Binding: the deletion problem will only be worse. trust me: i've tried it.
you could easily pass the model as an argument. as for NavigationLink and .sheet, they are different presentation styles (one "pushes" something on to the navigation stack with a BackButton, while the other does essentially a modal presentation).
i think this is a good idea -- to assign a UUID to most everything that i might need to locate later; and thanks for asking this question! it helps me with a problem i am working on and was pretty much settled on what was happening and how to solve it, but this code helped me think a little more clearly about it, or at least arrive at a plausible explanation. hope that helps, DMG |
|
Hi DMG, thanks for your answer. I think it will work for my textfield. But what if I want to use a Nico |
|
hi Nico, sorry for the slightly tortured explanation i gave earlier ... i reread that this morning and i still have confusion ... but at least we got what you needed. and it was especially helpful that but then you asked about a so i would propose a general situation for you:
how this last step is done depends on the presentation. if SubView was presented with a navigation link, then hook into its .onDisappear() modifier to do the transfer back to the item. if SubView was presented as a sheet, then the sheet probably has a "Save" button on it so that, when tapped, it does the transfer and dismisses the sheet. here's suitable code for the navigation situation that you have:
hope that helps, DMG |
|
I ran into the same issue, my workaround was slightly different. In the sub view, I left itemIndex as an optional. Then in the body I check if itemIndex is nil. If it is nil show only the text "No data" is displayed (note: this should never occur), otherwise show my regular view. Since itemIndex is no longer being forced unwrapped, we no longer have crashes when deleting items. All together it looks like this:
|
TAKE YOUR SKILLS TO THE NEXT LEVEL If you like Hacking with Swift, you'll love Hacking with Swift+ – it's my premium service where you can learn advanced Swift and SwiftUI, functional programming, algorithms, and more. Plus it comes with stacks of benefits, including monthly live streams, downloadable projects, a 20% discount on all books, and free gifts!
Sponsor Hacking with Swift and reach the world's largest Swift community!
This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.
All interactions here are governed by our code of conduct.
Link copied to your pasteboard.