我正在尝试将具有键入新值的数组项更新到Textfield中,但是List不会使用已编辑的值进行更新。
我的代码是:
型号:
struct WalletItem: Identifiable{
let id = UUID()
var name:String
var cardNumber:String
var type:String
var cvc:String
let pin:String
var dateOfExpiry:String
}
ModelView:
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")
})
}
}
PS:如果我使用@Binding而不是@State,则在第一个视图中会出现错误:初始化程序init(_:)
要求Binding<String>
符合StringProtocol
答案 0 :(得分:5)
这里是经过修改的部分(经过测试并可以在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)
}
}
答案 1 :(得分:1)
这是approach that Asperi suggested的简化独立示例:
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 = 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(Array(bookingModel.positions.enumerated()), id: \.element.id) { i, pos 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()
}
}