过滤列表项后,ListView中的SwiftUI TextField变为空白

时间:2019-10-30 08:59:18

标签: listview textfield swiftui

我正在使用一个iOS应用程序,该应用程序显示可以编辑的项目列表。为此,我将ListTextField用于每个项目。

我的应用程序具有一些按钮,允许用户筛选此列表中当前显示的信息。我遇到了一个问题,该问题导致TextField值在过滤后变为空白,而且我终生无法弄清楚自己在做什么错。

这是一个非常基本的复制品:

import SwiftUI

let allItems = ["1. Foo", "1. Bar", "1. Baz", "2. Goo", "2. Gar", "2. Gaz"]

struct ContentView: View {
    @State private var items = [String]()
    @State private var filterPrefix = "1"

    var body: some View {
        NavigationView {
            List {
                ForEach(items, id: \.self) { item in
                    RowView(item: item)
                }
            }
            .navigationBarItems(trailing: Button("Toggle") {
                self.filterPrefix = (self.filterPrefix == "1" ? "2" : "1")
                self.items = allItems.filter { $0.starts(with: self.filterPrefix) }
            })
            .navigationBarTitle("Items", displayMode: .inline)
        }
        .onAppear {
            self.items = allItems.filter { $0.starts(with: self.filterPrefix) }
        }
    }
}

struct RowView: View {
    var item: String

    @State private var inputText = ""

    var body: some View {
        VStack {
            TextField("", text: $inputText)
        }
        .onAppear {
            print("Item: \(self.item)") // This prints the item successfully
            self.inputText = self.item
        }
    }
}

几次击中Toggle时,TextField最终变成了空白。但是,onAppear中的代码仍然可以很好地打印文本值。

这是一个gif:

Example


我做错什么了吗?我是否应该仅在单击时抛出TextField? (似乎不是一个好主意,但我不知道为什么它不起作用)

我正在Xcode 11.2 beta 2(11B44)上运行,但是在11.1和iOS 13.1和13.2上都发生了相同的问题


编辑:为了进一步使事情复杂化,我将行更改为同时包含文本和文本字段:

        HStack {
            Text(item)
            TextField("", text: $inputText)
        }

现在TextField的值将变为空白,除非它是列表中的最后一项。对我来说开始像臭虫了

2 个答案:

答案 0 :(得分:0)

此问题已在最新的Xcode beta(11.4)中修复

答案 1 :(得分:-1)

只需将您的项数组过滤到位:

struct FilterView: View {

    @State private var items = ["1. Foo", "1. Bar", "1. Baz",
                                "2. Goo", "2. Gar", "2. Gaz"]
    @State private var filterPrefix = "1"

    var body: some View {
        NavigationView {
            List {
                ForEach(items.filter({ $0.starts(with: self.filterPrefix) }), id: \.self) { item in
                    RowView(item: item)
                }
            }
            .navigationBarItems(trailing: Button("Toggle") {
                self.filterPrefix = (self.filterPrefix == "1" ? "2" : "1")
            })
            .navigationBarTitle("Items", displayMode: .inline)
        }
    }
}