Your Second iOS and SwiftUI App · Binding | raywenderlich.com

I just tried that in my project and it worked. Cool!

I got the app to crash with the extension added: Fatal error: Index out of range
I played a little bit around removing, moving and editing. When I came down to 2 or 3 items it crashed…

I’m experiencing the same range exception as qmlearner2011 when deleting from a small list (1-3 items). Things work pretty well with or without the extension…except for that crash.

I had this problem as well. Switching to the enumerated array code worked for me.

Thanks in advance for your patience…

In this tutorial, it seems that the NavigationLink is used to get to an editable mode. In my app, NavigationLink is used to navigate to a child entity of the parent: From a House to a Room in the House for example. I then want to edit the attributes of the room. I wanted to use a conditional based on if I was in editing mode to determine the view I get to. Take me from the House to the list of rooms if I am not in edit mode, but take me to the EditHouseView if I am in edit mode. But no examples seem to be doing that. I am a 2 year old newbie and just want to finish my app lol… The only thing I can not get to work is updating my entities. How do I present the editRoomView if I am using the navigation links to navigate my data model… I have learned a ton from you all, thanks. I am just missing what I need to finish the app…

NavigationLink(destination: isEditing ?? EditPropertyView(property: property) : PropertyDetailView(property: property)){
PropertyRowView(property: property)
}

Am I not supposed to use the navigation link to traverse relationships between entities?
Is edit mode just for deleting objects and not editing them?

So far, SwiftUI seems to offer no way to do what you want to do. :slightly_frowning_face: (Discussion in the comments for the Edit Mode episode.) Instead, I think you’ll need to rely on another switching mechanism than the Edit Mode button.

1 Like

delete the last item
then click any item
will crash
index out of range

@ys_xs Do you still have issues with this?

using sample end code provided here in this page
still have the same problem

Hi! Yes in this scenario the app crashes…
I have another remark, if I tap a task and then go back, I can’t open it again… ^^’

I followed every step of the whole ‘Your Second iOS and SwiftUI App’ and even re-created a new project, but every time I reach this episode, i get an error. When I remove the .indices from taskStore.tasks in contentview, i get an error saying "Cannot convert value of type ‘[Task]’ to expected argument type ‘Range’ ". I have tried to figure this out myself, and even after recreating the project, I still got the same result.
Is anyone else having the same issue? Am i possibly missing something? Anything you have will help, thanks!

1 Like

I recommend using Git to find the exact differences between versions of a project. Are you familiar with it? If not, upload your version and I’ll let you know what it has to say!

Also recommended!
https://www.raywenderlich.com/4418-beginning-git
https://www.raywenderlich.com/4289-mastering-git

Hi. Thanks as always for the thorough walkthrough in every video! Though, I seem to be having a difficulty in understanding the last two episode, and I was wondering if I’m the only person and therefore need to go over them again to understand the concepts before I go any further. Thanks!

Feel free to continue on with this course, and see if you can get by with incomplete understanding. We all have incomplete understanding of these topics, after all! :smile_cat: They’re too huge to know everything about. The key is to keep practicing and building knowledge up incrementally.

If the rest of this course gives you trouble, then try a later one in the learning path, and come back to this one after a break. It could help!

Hi, I had the same issue. I believe when you copied the extension folders, you had selected “Create folder references” instead of “Create groups”. With “Create folder references”, the folder icon is in blue and not yellow as it should be. Hope this helps!

2 Likes

@jessycatterwaul I’m very confused as to when to use bindings, and when to use classes.

In the RowView file, we accept a @Binding, and pass that down to the TaskEditingView.

However, we have another view that we are passing down the entire “task store” class to, but not using a binding (not even sure that’s possible).

When we append to the task array, it all works fine and updates the state, even though we’re not using a binding.

How can NewTaskView edit the “task store” without needing a binding, but when I tried to make the “task” struct a class, and pass that down to the TaskEditingView, and modify it’s name property, the changes would not be reflected at all.

I’m seriously confused as to when and how we should use @Binding vs Classes and why classes sometimes work as references in SwiftUI and sometimes don’t.

Can anyone explain or follow up with me?

I’m very confused as to when to use bindings, and when to use classes.

That’s reasonable! They can solve the same problems. So the choice isn’t a matter of technical restrictions, but architectural design.

Who owns the model? Can you realistically say that a view does? If so, State+Bindings are how to represent that.

If, like in this app, the model really belongs to an ancestor of multiple views, and that thing itself is not a view (e.g. it’s the “app” itself), then an observable object is a better representation.

(not even sure that’s possible).

It’s possible. Using Binding on a reference type will allow you to reassign the reference, for all views. Generally, that’s not going to be necessary, or a good idea! Reassigning references for other instances makes for hard to follow code, and is normally a more complex way of going about a task than it needs to be.

How can NewTaskView edit the “task store” without needing a binding…

ObservableObject+Published+ObservedObject.

…but when I tried to make the “task” struct a class, and pass that down to the TaskEditingView, and modify it’s name property, the changes would not be reflected at all.

Building with Xcode 11.4, the changes are reflected, for me. Like I went over in the Observable Objects episode, don’t try to make predictions about whether the changes in the model are going to be reflected in the UI, without a guarantee. Otherwise, the results will change unexpectedly.

1 Like

@jessycatterwaul Thanks for your prompt response! You clarified a lot for me but I am still confused on my experiment to pass down a “task class” and edit it. When I do this in the “RowView.swift file” like so:

	struct RowView: View {

	var task: Task

	var body: some View {
		Button(action: { self.task.name = "This new name should be shown but is not!" }) {
			Text(task.name).strikethrough(task.completed)
		}


	}
}

The new name is not updated in the list. It will be however, if I open the the NewTaskView, which forces a re-render.

I don’t understand how ObservedObject can listen to the appending of the array (without a binding), but cannot listen to the change of a reference type’s property in that array.

Are you using the 11.4 beta? That’s not the behavior I get. Only the new rows re-render.

In order to see what you’re seeing, I need to change the Identifiable behavior of Task. Again, this is all subject to change. Don’t put any faith in SwiftUI magically working, when there are ways to force it to work.

Arrays are value types. @Published is just a shortcut to calling objectWillChange in the array’s willSet observer (with some async magic to make it more like didSet).

@jessycatterwaul Maybe this is because I’m displaying RowViews like this?

ForEach(
  Array( taskStore.tasks.enumerated() ),
  id: \.element.id
) { index, _ in
  RowView(task: self.taskStore.tasks[index])
}