【问题标题】:SwiftUI Reload ViewSwiftUI 重新加载视图
【发布时间】:2021-11-19 21:25:20
【问题描述】:

我有一个结构,它可以从 CoreData 中洗牌和列出记录。 我想用按钮重新加载/刷新列表视图。 我尝试使用 Button 中的功能。 有什么办法可以做到吗?

    var body: some View {


            VStack {

                       List {

                           ForEach(dictionary.shuffled().prefix(upTo: 10),id: \.self) { word in


                            HStack {
                               Text("\(word.englishWord)")
                                    .foregroundColor(Color.blue)

                                Text("| \(word.urhoboWord) |")
                                    .foregroundColor(Color.green)

                                Image(word.imageName)
                                    .resizable()
                                    .frame(width:40, height: 40)


                            }//HStack

                           }//End of ForEach

                        }//End of List

                //Button to reload and shuffle list
                Button(action: {}) {

                    Text("Shuffle")
                        .padding()
                        .background(Color.black)
                        .foregroundColor(Color.white)
                        .cornerRadius(6)
                }


                        .navigationBarTitle(Text("Begin Learning"),displayMode: .inline)


【问题讨论】:

    标签: swiftui


    【解决方案1】:

    您应该将此dictionary.shuffled().prefix(upTo: 10) 移动到您的ViewModel,然后您的视图将根据数据重新加载。 看看这段代码以供参考:

    struct SampleShuffleView : View {
        @ObservedObject var viewModel : ShuffleViewModel = ShuffleViewModel()
    
        var body : some View {
            VStack {
                List(self.viewModel.listData, id: \.self) { str in
                    Text(str)
                }
    
                Button(action: self.shuffle) {
                    Text("Shuffle me").padding()
                }.background(Color.white).padding()
    
            }
        }
    
        func shuffle() {
            self.viewModel.shuffle()
        }
    }
    
    class ShuffleViewModel : ObservableObject {
        @Published var listData = ["one", "two", "three", "four"]
    
        func shuffle() {
            listData.shuffle()
            //or listData = dictionary.shuffled().prefix(upTo: 10)
        }
    }
    

    注意:当@ObservedObject 更改时,所有视图的组件都将重新加载,因此请考虑分离较小的视图-视图模型,或使用@State 变量。

    希望这会有所帮助。

    【讨论】:

      【解决方案2】:

      只需触发@ObservableObject@State@Published 的任何值。 如果您没有,只需创建一个:

      @State var refresh: Bool = false
      
      func update() {
         refresh.toggle()
      }
      

      【讨论】:

      • 会补充一点,如果您有一个带有对象的对象或视图中的视图,那么您放置状态变量的位置可能是相关的——必须在 NavigationView 上方上一层才能获得列表更新,当下游详细视图更改列表中显示的文本时。
      • 看来您还需要在视图构建器中使用更新后的值,否则更改将被忽略,例如.background(Color.clear.disabled(refresh)).
      【解决方案3】:

      想一想。要在点击时显示数组和随机播放,请完全按照您的意愿进行操作。首先以某种类似“列表”的方式向我们展示数组,然后根据用户操作对其进行洗牌。

      struct ContentView: View {
          @State var arr = ["ALFA", "BETA", "GAMA", "DELTA"]
          var body: some View {
              VStack {
              VStack {
                  Divider()
                  ForEach(arr, id: \.self) { element in
                      VStack {
                          Text(element)
                          Divider()
                      }
                  }
              }
                  Spacer()
                  Button(action: {
                      self.arr.shuffle()
                  }) {
                      Text("Shuffle")
                  }
                  Spacer()
              }
          }
      }
      

      arr.shuffle() 更改了 View 的 @State 并强制 SwiftUI 自动“重新加载”。

      【讨论】:

      • @Ahmadreza 请说明在您的具体情况下什么不起作用。
      • 在我的情况下它不会强制子视图更新。
      猜你喜欢
      • 1970-01-01
      • 2020-05-23
      • 2020-12-29
      • 1970-01-01
      • 2020-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多