SwiftUI View Dismisses when typing in TextField

I’m experiencing a super weird/annoying quirk where modifying an @ObservedRealmObject property, the view dismisses or pops to the previous view in the navigation stack.

The oddest part is that modifying properties on other objects also using the same property wrapper aren’t popping / dismissing.

One of them is a linked object on the other, so maybe that’s the issue?

Here are how the objects are modeled:

class Plan: Object, ObjectKeyIdentifiable {
  @Persisted(primaryKey: true) var _id = UUID()
  @Persisted var location: Location?
  @Persisted var name: String = ""
}

class Location: Object, ObjectKeyIdentifiable {
  @Persisted(primaryKey: true) var _id = UUID()
  @Persisted var name: String = ""
}

If I write to the Plan using $plan.name it works.

I can’t write to the Location using $plan.location.name but I can pass it into its own view and write to $location.name, each key stroke dismisses the view.

My workaround is to move the props I need to write to into the Plan object instead of the Location object, but if anyone has seen this behavior or understands why it’s happening, I’d really like to know how to handle the data correctly so that this won’t happen.

This is still happening all over my app with different views for me and I can’t always work around it.

Anyone know what I’m doing wrong? @Jason_Flax? @Andrew_Morgan?

So, you’re passing $location.name directly to textField? That’s not something I’ve tried as I always pass a local state variable and then use that to update the realm objects when done. I can give it a try.

Yeah, that’s for the implicit writes. I’m trying absolutely everything ( trying to switch between @ObservedRealmObject, @StateRealmObject, @Binding, no property wrappers, etc. ) to figure out what’s causing it, but I can’t figure it out.

Basically everything I try in this app is plagued by this where I just can’t keep working on it. So frustrating.

I got to the point where I am trying to provide edit screens and every time you type to edit a field, every keystroke pops the view and the last thing I want to do is start mapping every stored property to a local property that then watches for changes and then writes on blur or dismissing screen or a save button to then update the object with changes from state variables. That is exactly what these implicit writes are supposed to be preventing.

Hi @Kurt_Libby1, not sure if I’m matching exactly what you’re trying to do here, but I did reproduce some odd behavior when updating location.name in a TextField: repo

If I type slowly when editing the location name, it works fine. If I type quickly then it locks up - and if I look at the realm file in Realm Studio I can see that the value rapidly toggles between the before and after values.

Thanks Andrew.

I’ve been playing around with your simplified repo and I was finally able to reproduce it.

I have a list of plans that i can then go to the detail screen. So there is a NavigationView with a NavigationLink(destination: PlanDetails(plan: plan).

Then, on the PlanDetails page I have an edit button in the toolbar that is also a NavigationLink(destination: EditLocation(location: location).

All of the editing works until the 2nd level of navigation. Once the second level of NavigationLink is introduced, every keystroke pops up a level.

I still have no idea why it’s doing this, but this should be easily reproducible now. Forked and added the 3rd level of Nav Stack here: GitHub - misterlib/PlanTest at addNavStack

Thanks Kurt, I’m seeing the same behavior as you with your fork. I tried a couple of things, but they didn’t help:

  • Converting Location to an EmbeddedObject
  • Using a local state variable to pass into the TextField and then copying it to the ObservedRealmObject when a “Save” button is tapped

It seems to be a combination of nested objects and passing it down multiple levels of views (where it’s an ObservableRealmObject in each view).

Figured it out! :tada:

According to this post, it’s a SwiftUI issue with all ObservedObjects, not just the Realm flavor.

Adding .isDetailLink(false) to the NavigationLink stops it. Something about the columns structure for iPad and the way that the links are handled, this allows the screen in the stack to stay put.

Just this one line did the trick:

Screen Shot 2022-03-15 at 10.29.21 AM

1 Like

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.