SwiftUI列表中的可编辑TextField

时间:2019-08-20 14:41:53

标签: swiftui appkit

在beta6 SwiftUI macOS(不是iOS系统)应用中,我需要有一个List带有可编辑的文本字段,但其中的TextField列表不可编辑。如果我将List换成Form(或仅换成VStack),则效果很好,但是我需要它与List一起使用。有什么技巧告诉列表使字段可编辑吗?

import SwiftUI

struct ContentView: View {
    @State var stringField: String = ""

    var body: some View {
        List { // works if this is VStack or Form
            Section(header: Text("Form Header"), footer: Text("Form Footer")) {
                TextField("Line 1", text: $stringField).environment(\.isEnabled, true)
                TextField("Line 2", text: $stringField)
                TextField("Line 3", text: $stringField)
                TextField("Line 4", text: $stringField)
                TextField("Line 5", text: $stringField)
            }
        }
    }
}

4 个答案:

答案 0 :(得分:2)

以下代码仅是了解SwiftUI中List的字符并显示替代方法的实验。通过观察各种组合的输出,我了解到的是,列表视图的样式在某种程度上可以覆盖基础视图的默认行为,使其变为“可选”。这意味着TextField完全不同。 TextField是我们可以输入的可聚焦元素。此焦点变量未连接到“列表视图”中以一起工作。因此,列表将覆盖默认的可聚焦对象。因此,不可能用TextView创建List。但是,如果需要,下一个最佳选择是ScrollView而不是List并显式地进行样式设置。并同时检查以下代码。

import SwiftUI

struct ContentView: View {
    @State private var arr = ["1","2","3"]
    var body: some View {
        HStack {
            VStack {
                List {
                    ForEach(self.arr.indices, id:\.self) {
                        TextField("", text: self.$arr[$0])
                    }
                }
            }
            .frame(minWidth: 150, maxWidth: .infinity, minHeight: 300, maxHeight: .infinity)
            VStack {
                ScrollView {
                    ForEach(self.arr.indices, id:\.self) {
                        TextField("", text: self.$arr[$0])
                        .textFieldStyle(PlainTextFieldStyle())
                        .padding(2)
                    }
                }
                .padding(.leading, 5)
                .padding(3)
            }
            .background(Color(NSColor.alternatingContentBackgroundColors[0]))
            .frame(minWidth: 150, maxWidth: .infinity, minHeight: 300, maxHeight: .infinity)
        }
    }
}

extension NSTextField {
    open override var focusRingType: NSFocusRingType {
        get { .none }
        set { }
    }
}

答案 1 :(得分:0)

错误报告

我将项目更新为针对MacOS应用程序,并找到了您要报告的错误。我已经用此反馈更新了Apple,因为它确实确实是个错误(欢迎使用Beta)。

  

FB7174245-嵌入在列表中的SwiftUI文本字段不可编辑   当目标是macOS

更新

那么下面所有关注状态和绑定的意义是什么?一个变量应绑定到单个控件。这是working example。我将保留较旧的答案,因为它通过完整的应用程序来保存和向CoreData检索数据以及从CoreData检索数据的方式继续进行示例。

$arr = (get-childitem "My Path" -recurse -Filter '*.*' -File)
  

BTW-可以在MacOS Catalina上的Xcode Beta(11M392r)上使用-10.15   Beta(19A546d)。

示例项目

请查看此sample,其中包括一个可编辑的Textfield,该文本字段写入了我在Github上构建的CoreData。

  

看看@State和@Binding之间的区别,以便您   可以从内容视图外部操作数据。 (60-sec video

import SwiftUI

//struct ContentView: View {
//    var body: some View {
//        Text("Hello World")
//    }
//}
struct ContentView: View {
    @State var field1: String = ""
    @State var field2: String = ""
    @State var field3: String = ""
    @State var field4: String = ""
    @State var field5: String = ""

    var body: some View {
        List { // works if this is VStack or Form
            Section(header: Text("Form Header"), footer: Text("Form Footer")) {
                TextField("Line 1", text: $field1).environment(\.isEnabled, true)
                TextField("Line 2", text: $field2)
                TextField("Line 3", text: $field3)
                TextField("Line 4", text: $field4)
                TextField("Line 5", text: $field5)
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

source

  

查看以下答案,以了解@State的适当用例   (SO Answer

答案 2 :(得分:0)

SwiftUI 2.0

您可以在列表中使用TextEditor代替TextField以获得可编辑的文本字段。

TextEditor(text: $strings)
    .font(.body)
    .cornerRadius(5)
    .shadow(color: Color.black.opacity(0.18), radius: 0.8, y: 1)
    .frame(height: 20)

这样,您将在TextEditor和TextField之间获得类似的外观。

答案 3 :(得分:0)

确实能获得焦点——如果你点击得恰到好处

将 Xcode 12.4 和 SwiftUI 2 用于 ma​​cOS 应用程序,我似乎遇到了同样的问题:无法使 TextEdit 在列表中工作。阅读此处并进行更多实验后,我意识到在我的情况下 TextField 确实可靠地获得了焦点,但前提是您以正确的方式点击。我认为并希望这不是它应该的工作方式,所以我发布了问题 TextField inside a List in SwiftUI on macOS: Editing not working well,解释了我的观察细节。

总而言之:在现有文本上精确单击确实可以提供焦点(经过一个小而烦人的延迟之后)。在任何地方双击都不会给焦点。单击空白字段中的任意位置确实可以获得焦点。