如何在 SwiftUI 中创建多行文本字段?
How do I create a multiline Textfiled in SwiftUI?
我正在尝试实现此视图(在屏幕截图上)。用户可以在此框中输入内容。他应该能够创建新的段落,但文本不应超过框的高度,例如使用 linelimit。目标:
但是,选择文本场时,该线在打字时会保持水平增长。我试图通过添加 ".linelimit(nil) 来修改,但它不起作用。
我的另一种方法是使用文本编辑器:
但也存在缺少占位符以及对布局和文本填充进行修改的问题。当我添加填充时,布局如下所示:
.
这是我使用 TextEditor 的情况:
struct Notes: View {
@State private var notes = ""
var body: some View {
VStack (alignment: .leading, spacing: 5) {
Text("Notes")
.fontWeight(.bold)
TextEditor(text: $notes)
.submitLabel(.done)
//.padding()
.frame(height: 100, alignment: .top)
//.background(Color(.systemGray5))
.lineLimit(3)
.cornerRadius(22)
.multilineTextAlignment(.leading)
.colorMultiply(Color(.systemGray5))
}
.frame(minWidth: 0, maxWidth: .infinity)
.padding(.horizontal)
}
}
我还缺少其他选择吗?
感谢您的建议和帮助。
亲切的问候。
这是一个 90% 的解决方案。它会在第 3 个换行符后删除更多文本,但无法检测长文本中的换行。
struct ContentView: View {
@State private var notes = ""
var body: some View {
VStack (alignment: .leading) {
Text("Notes")
.fontWeight(.bold)
CustomTextEditor("Enter your note", text: $notes)
}
.padding()
}
}
struct CustomTextEditor: View {
init(_ prompt: LocalizedStringKey, text: Binding<String>) {
self.prompt = prompt
self._text = Binding(projectedValue: text)
}
let prompt: LocalizedStringKey
@Binding var text: String
var body: some View {
ZStack(alignment: .topLeading ) {
Text(prompt)
.foregroundColor(text == "" ? .secondary : .clear)
.padding(EdgeInsets(top: 7, leading: 3, bottom: 0, trailing: 0))
TextEditor(text: $text)
// deleting everything after the 3rd linebreak
.onChange(of: text) { _ in
let stringArray = text.map { [=10=] }
let pos = stringArray.indices.filter { stringArray[[=10=]] == "\n"}
if pos.count > 2 {
text = String(stringArray.prefix(upTo: pos[2]))
}
}
}
.frame(height: 82)
.padding(10)
.background(Color(.systemGray5))
.cornerRadius(20)
// getting rid of TextEditor standard background
.onAppear {
UITextView.appearance().backgroundColor = .clear
}
.onDisappear {
UITextView.appearance().backgroundColor = .systemGray5
}
}
}
我正在尝试实现此视图(在屏幕截图上)。用户可以在此框中输入内容。他应该能够创建新的段落,但文本不应超过框的高度,例如使用 linelimit。目标:
但是,选择文本场时,该线在打字时会保持水平增长。我试图通过添加 ".linelimit(nil) 来修改,但它不起作用。
我的另一种方法是使用文本编辑器:
但也存在缺少占位符以及对布局和文本填充进行修改的问题。当我添加填充时,布局如下所示:
这是我使用 TextEditor 的情况:
struct Notes: View {
@State private var notes = ""
var body: some View {
VStack (alignment: .leading, spacing: 5) {
Text("Notes")
.fontWeight(.bold)
TextEditor(text: $notes)
.submitLabel(.done)
//.padding()
.frame(height: 100, alignment: .top)
//.background(Color(.systemGray5))
.lineLimit(3)
.cornerRadius(22)
.multilineTextAlignment(.leading)
.colorMultiply(Color(.systemGray5))
}
.frame(minWidth: 0, maxWidth: .infinity)
.padding(.horizontal)
}
}
我还缺少其他选择吗?
感谢您的建议和帮助。 亲切的问候。
这是一个 90% 的解决方案。它会在第 3 个换行符后删除更多文本,但无法检测长文本中的换行。
struct ContentView: View {
@State private var notes = ""
var body: some View {
VStack (alignment: .leading) {
Text("Notes")
.fontWeight(.bold)
CustomTextEditor("Enter your note", text: $notes)
}
.padding()
}
}
struct CustomTextEditor: View {
init(_ prompt: LocalizedStringKey, text: Binding<String>) {
self.prompt = prompt
self._text = Binding(projectedValue: text)
}
let prompt: LocalizedStringKey
@Binding var text: String
var body: some View {
ZStack(alignment: .topLeading ) {
Text(prompt)
.foregroundColor(text == "" ? .secondary : .clear)
.padding(EdgeInsets(top: 7, leading: 3, bottom: 0, trailing: 0))
TextEditor(text: $text)
// deleting everything after the 3rd linebreak
.onChange(of: text) { _ in
let stringArray = text.map { [=10=] }
let pos = stringArray.indices.filter { stringArray[[=10=]] == "\n"}
if pos.count > 2 {
text = String(stringArray.prefix(upTo: pos[2]))
}
}
}
.frame(height: 82)
.padding(10)
.background(Color(.systemGray5))
.cornerRadius(20)
// getting rid of TextEditor standard background
.onAppear {
UITextView.appearance().backgroundColor = .clear
}
.onDisappear {
UITextView.appearance().backgroundColor = .systemGray5
}
}
}