更新模型时,明细视图未更新(使用列表)SwiftUI [英] Detail View is not updated when the model is updated (Using List) SwiftUI

查看:60
本文介绍了更新模型时,明细视图未更新(使用列表)SwiftUI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用列表在主视图中显示模型.当我在详细视图中更新模型时,不会在详细视图中更新它.

当我不使用 List 时,详细信息视图将更新.我缺少列表的什么?


  struct Person:可识别的{var ID:UUID变量名称:字符串}类PersonModel:ObservableObject {@已发布的var人员:[Person] = [Person(id:UUID(),名称:"Ege"))}struct PersonListView:查看{@StateObject私有var personModel = PersonModel()var body:some View {NavigationView {列表 {ForEach(personModel.persons){NavigationLink(目的地:PersonDetailView(person:person).environmentObject(personModel)){文字(人名)}}}.navigationTitle(人")}}}struct PersonDetailView:查看{让人:人@EnvironmentObject var personModel:PersonModelvar body:some View {VStack {文字(人名)按钮(操作:{让personIndex = personModel.persons.firstIndex(其中:{$ 0.id == person.id})!personModel.persons [personIndex] .name =更新名称";}){文字(更新")}}.navigationTitle(人员详细信息")}} 

我用于列表的解决方法:

  • 为NavigationLink使用自定义绑定功能.

示例代码:

 //1私人功能绑定(对于个人:个人)->绑定<人>{让personIndex = personModel.persons.firstIndex(其中:{$ 0.id == person.id})?0返回$ personModel.persons [personIndex]}//2NavigationLink(目标:PersonDetailView(person:绑定(for:person)))//3@Binding var person:Person//详细视图 

  • 在详细信息视图中使用另一个 @State ,该视图已通过初始化onAppear方法中的模型.

解决方案

在我看来,尽管您的解决方法肯定行得通,但您还是想知道正在发生什么,以及为什么首先需要解决方法.>

当您更新您的 @Published var person:[Person] 数组的值时,您的详细信息视图将按照您的期望重新呈现.但是,您要告诉您的视图打印未更改的 var person:Person 结构的 name 值.仍然与第一次创建视图时相同.

如果您替换

 文本(person.name) 

使用

  Text(personModel.persons.first(其中:{$ 0.id == person.id})!. name) 

它会按预期更新,因为您要为Text视图提供从实际 PersonModel中提取的 person 新版本的 name 您刚刚更新的.

因此, List 的参与似乎并不是问题所在,这就是为什么我没有直接回答您的问题" List 我缺少什么??".希望它仍然可以帮助您!

I am using List to show the models in the main view. When I update the model in detail view it is not updated in detail view.

When I don't use List, detail view is updated. What am I missing for List?


struct Person: Identifiable {
  var id: UUID
  var name: String
}

class PersonModel: ObservableObject {
  @Published var persons: [Person] = [Person(id: UUID(), name: "Ege")]
}

struct PersonListView: View {
  
  @StateObject private var personModel = PersonModel()
  
  var body: some View {
    NavigationView {
      List {
        ForEach(personModel.persons) { person in
          NavigationLink(destination: PersonDetailView(person: person).environmentObject(personModel)) {
            Text(person.name)
          }
        }
      }
      .navigationTitle("Persons")
    }
  }
}

struct PersonDetailView: View {
  
  let person: Person
  @EnvironmentObject var personModel: PersonModel
  
  var body: some View {
    VStack {
      Text(person.name)
      
      Button(action: {
        let personIndex = personModel.persons.firstIndex(where: { $0.id == person.id })!
        personModel.persons[personIndex].name = "Updated Name"
      }) {
        Text("Update")
      }
    }
    .navigationTitle("Person Detail")
  }
}

Workarounds that I used for List:

  • Using custom binding function for NavigationLink.

Example code:

//1
private func binding(for person: Person) -> Binding<Person> {
  let personIndex = personModel.persons.firstIndex(where: { $0.id == person.id }) ?? 0
  return $personModel.persons[personIndex]
}
//2
NavigationLink(destination: PersonDetailView(person: binding(for: person)))
//3
@Binding var person: Person //DetailView

  • Using another @State in detail view which is initialized with passed model in onAppear method.

解决方案

It seems to me that, although your workaround surely works, you'd like to know what's happening and why you need a workaround in the first place.

When you update the value of your @Published var persons: [Person] array, your detail view is re-rendered as you would expect. But you are telling your view to print the name value of the var person: Person struct which hasn't changed. It's still the same as when the view was first created.

If you replace

Text(person.name)

with

Text(personModel.persons.first(where: { $0.id == person.id } )!.name)

it updates as you would expect, because you're providing the Text view with the name value of the new version of person pulled from your actual PersonModel that you just updated.

So the involvement of List doesn't seem to be the issue, which is why I haven't directly answered your question "What am I missing for List?". Hopefully it helps anyway!

这篇关于更新模型时,明细视图未更新(使用列表)SwiftUI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆