【问题标题】:SwiftUI: How to update passing array item in the other viewSwiftUI:如何在另一个视图中更新传递的数组项
【发布时间】:2020-02-26 19:24:39
【问题描述】:

我正在尝试使用在 Textfield 中键入的新值更新数组项,但未使用编辑值更新列表。

我的代码是:

型号:

    struct WalletItem: Identifiable{

        let id = UUID()
        var name:String
        var cardNumber:String
        var type:String
        var cvc:String
        let pin:String
        var dateOfExpiry:String
    }

模型视图:

    class Wallet: ObservableObject{

        @Published var wallets = [
            WalletItem(name: "BSB", cardNumber: "123456789", type: "master card", cvc: "1234", pin: "1234", dateOfExpiry: "2016-06-29"),
            WalletItem(name: "Alpha bank", cardNumber: "123456789", type: "master card", cvc: "1234", pin: "1234", dateOfExpiry: "2017-03-12"),
            WalletItem(name: "MTБ", cardNumber: "123456789", type: "master card", cvc: "1234", pin: "1234", dateOfExpiry: "2020-11-12"),
        ]

    }

第一次查看:

    struct WalletListView: View {

        // Properties
        // ==========

        @ObservedObject var wallet = Wallet()
        @State var isNewItemSheetIsVisible = false


        var body: some View {
            NavigationView {
                List(wallet.wallets) { walletItem in
                    NavigationLink(destination: EditWalletItem(walletItem: walletItem)){
                            Text(walletItem.name)
                        }
                }
                .navigationBarTitle("Cards", displayMode: .inline)
                .navigationBarItems(
                    leading: Button(action: { self.isNewItemSheetIsVisible = true
                    }) {
                        HStack {
                            Image(systemName: "plus.circle.fill")
                            Text("Add item")
                        }
                    }
                )
            }
            .sheet(isPresented: $isNewItemSheetIsVisible) {
                NewWalletItem(wallet: self.wallet)
            }
        } 

    }

次要观点:

    struct EditWalletItem: View {

        @State var walletItem: WalletItem


        @Environment(\.presentationMode) var presentationMode

        var body: some View {
            Form{
                Section(header: Text("Card Name")){
                    TextField("", text: $walletItem.name)
                }

            }
            .navigationBarItems(leading:
                Button(action: {
                    self.presentationMode.wrappedValue.dismiss()
                })
                {
                    Text("Back")
                }, trailing:
                Button(action: {

                    self.presentationMode.wrappedValue.dismiss()
                })
                {
                    Text("Save")
            })

        }

    }

P.S:如果我使用@Binding 而不是@State,我在第一个视图中会出现错误:初始化程序init(_:) 要求Binding<String> 符合StringProtocol

【问题讨论】:

    标签: ios swiftui


    【解决方案1】:

    这里是修改过的部分(测试并适用于 Xcode 11.2 / iOS 13.2):

    1) 确定过度绑定

    struct EditWalletItem: View {
        @Binding var walletItem: WalletItem
    

    2) 传递地点

    List(Array(wallet.wallets.enumerated()), id: \.element.id) { (i, walletItem) in
        NavigationLink(destination: EditWalletItem(walletItem: self.$wallet.wallets[i])){
                Text(walletItem.name)
            }
    }
    

    【讨论】:

      【解决方案2】:

      ForEach(Array(list.enumerated())) 只有在列表是 Array 而不是 ArraySlice 时才能正常工作,并且它具有复制列表的缺点。

      更好的方法是使用.indexed() 助手:

      struct IndexedCollection<Base: RandomAccessCollection>: RandomAccessCollection {
          typealias Index = Base.Index
          typealias Element = (index: Index, element: Base.Element)
          let base: Base
          var startIndex: Index { self.base.startIndex }
          var endIndex: Index { self.base.endIndex }
      
          func index(after i: Index) -> Index {
              self.base.index(after: i)
          }
      
          func index(before i: Index) -> Index {
              self.base.index(before: i)
          }
      
          func index(_ i: Index, offsetBy distance: Int) -> Index {
              self.base.index(i, offsetBy: distance)
          }
      
          subscript(position: Index) -> Element {
              (index: position, element: self.base[position])
          }
      }
      
      extension RandomAccessCollection {
          func indexed() -> IndexedCollection<Self> {
              IndexedCollection(base: self)
          }
      }
      

      例子:

      // SwiftUIPlayground
      // https://github.com/ralfebert/SwiftUIPlayground/
      
      import Foundation
      import SwiftUI
      
      struct Position {
          var id = UUID()
          var count: Int
          var name: String
      }
      
      class BookingModel: ObservableObject {
      
          @Published var positions: [Position]
      
          init(positions: [Position] = []) {
              self.positions = positions
          }
      
      }
      
      struct EditableListExample: View {
      
          @ObservedObject var bookingModel = BookingModel(
              positions: [
                  Position(count: 1, name: "Candy"),
                  Position(count: 0, name: "Bread"),
              ]
          )
      
          var body: some View {
              // >>> Passing a binding into an Array via index:
              List(bookingModel.positions.indexed(), id: \.element.id) { i, _ in
                  PositionRowView(position: self.$bookingModel.positions[i])
              }
          }
      }
      
      struct PositionRowView: View {
      
          @Binding var position: Position
      
          var body: some View {
              Stepper(
                  value: $position.count,
                  label: {
                      Text("\(position.count)x \(position.name)")
                  }
              )
          }
      
      }
      
      struct EditableListExample_Previews: PreviewProvider {
          static var previews: some View {
              EditableListExample()
          }
      }
      

      另见:

      【讨论】:

        猜你喜欢
        • 2021-09-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-07-29
        • 1970-01-01
        • 2021-08-04
        • 1970-01-01
        相关资源
        最近更新 更多