SwiftUI TextField(MacOS)的异常行为

时间:2019-10-05 18:17:44

标签: swift swiftui

在MacOS应用程序(XCode 11.0稳定版,CoreData)上使用SwiftUI时,我遇到了TextFields的奇怪行为,这可能是由于我对SwiftUI数据流存在一些误解。

实施

请考虑以下基本的“主视图/详细视图”设置:

  • 型号:Account
  • 容器:ContentView
  • 主人:AccountListView
  • 详细信息:AccountEditView
final class Account: NSManagedObject, Identifiable {
            @NSManaged var id: UUID
            @NSManaged var name: String
        }

struct ContentView: View {
    var body: some View {
        NavigationView {
            AccountListView()
                .listStyle(SidebarListStyle())
        }
        .navigationViewStyle(DoubleColumnNavigationViewStyle())
        .frame(minWidth: 300, idealWidth: nil, maxWidth: nil, minHeight: 300, idealHeight: nil, maxHeight: nil, alignment: .topLeading)
    }
}

struct AccountListView: View {

    @FetchRequest(entity: Account.entity(), sortDescriptors: [])
    var accounts: FetchedResults<Account>

    var body: some View {
        VStack {
            List(accounts) { account in
                NavigationLink (destination: AccountEditView(account: account)) {
                    Text(account.name)
                }
            }
        }
    }
}

struct AccountEditView: View {

    @ObservedObject var account: Account

    var body: some View {
        VStack {
            TextField("Account Name", text: $account.name)
            Spacer()
        }
    }
}

问题

已正确填充视图。在列表视图中选择一个帐户可以正确更新详细信息视图中的文本字段。

但是,一旦我编辑了textfield值,事情就会变得很奇怪:

  • 新近更新详细信息视图时,文本字段在第一个输入字符之后失去焦点。列表视图中的帐户名称已正确更新(显示输入的单个字符)
  • 当我再次输入文本格式时,我可以键入更多字符而不会失去焦点(再次,列表视图中的帐户名已更新)
  • 按下Enter键后,TextField的值将恢复为旧值,而列表视图的值仍保持为更新后的值。
  • 在不同的帐户条目之间来回切换时,详细信息视图显示正确的值。因此,模型对象已正确更新。

我的问题:

  1. 为什么第一次输入单个字符时TextField失去焦点
  2. 为什么在提交更改时TextField还原其先前的值(而不是模型值)

很抱歉,这个冗长的问题...

1 个答案:

答案 0 :(得分:0)

coredata属性是另一种可选的。因此,我们需要在Model类中定义getter和setter来转换其行为。

如果您实体的代码生成不是手动/无,请在contentview中添加以下代码

extension Account {
    var wrappedName: String {
        get { name ?? "Unknown"}
        set { name = newValue }
    }
}

然后将所有account.name替换为account.wrappedName

P.S。这已经在MacOS 10.5的XCode 11.4中进行了测试和工作