我想TextEditor在我的 ForEach 中有一些,我在 down 中制作了这个示例代码!正如您在 Image 中看到的代码和结果,它TextEditor就像一个贪婪的视图,并占用所有可用空间!至少对我来说有很多缺点!
如果我将高度限制为自定义值,那么我将失去查看 TextEditor 本身的所有字符串和字符串行的可能性,并且我必须向上或向下滚动才能看到其他行,这不是我的设计!
我的目标是占用TextEditor所需的空间,如果我输入新的字符串行,那么它的高度可以增加,或者如果我删除字符串行,它的高度可以缩小到至少 1 行!
我想知道我该怎么做?
struct ContentView: View {
@StateObject var textEditorReferenceType: TextEditorReferenceType = TextEditorReferenceType()
var body: some View {
Text("TextEditorView").bold().padding()
VStack {
ForEach(textEditorReferenceType.arrayOfString.indices, id: \.self, content: { index in
TextEditorView(string: $textEditorReferenceType.arrayOfString[index])
})
}
.padding()
}
}
struct TextEditorView: View {
@Binding var string: String
var body: some View {
TextEditor(text: $string)
.cornerRadius(10.0)
.shadow(radius: 1.0)
}
}
class TextEditorReferenceType: ObservableObject {
@Published var arrayOfString: [String] = ["Hello, World!", "Hello, World!", "Hello, World!"]
}
Run Code Online (Sandbox Code Playgroud)
jn_*_*pdx 28
您可以使用PreferenceKey和 不可见的Text覆盖层来测量字符串尺寸并设置 的TextEditor框架:
struct TextEditorView: View {
@Binding var string: String
@State var textEditorHeight : CGFloat = 20
var body: some View {
ZStack(alignment: .leading) {
Text(string)
.font(.system(.body))
.foregroundColor(.clear)
.padding(14)
.background(GeometryReader {
Color.clear.preference(key: ViewHeightKey.self,
value: $0.frame(in: .local).size.height)
})
TextEditor(text: $string)
.font(.system(.body))
.frame(height: max(40,textEditorHeight))
.cornerRadius(10.0)
.shadow(radius: 1.0)
}.onPreferenceChange(ViewHeightKey.self) { textEditorHeight = $0 }
}
}
struct ViewHeightKey: PreferenceKey {
static var defaultValue: CGFloat { 0 }
static func reduce(value: inout Value, nextValue: () -> Value) {
value = value + nextValue()
}
}
Run Code Online (Sandbox Code Playgroud)
改编自我的其他答案:Mimicing behavior of iMessage with TextEditor for text input
wil*_*ard 25
在 iOS 16 中,现在可以通过textField添加axis: .vertical和.lineLimit()
linelimit 定义文本字段扩展之前的行数。添加开始范围以定义文本字段内的行范围将开始和停止延伸。
WWDC22 会议“SwiftUI 的新增功能”17:10 左右
添加.fixedSize(horizontal: false, vertical: true)最小高度为我解决了这个问题。
例子 :
TextEditor(text: $myBinding)
.frame(minHeight: 50)
.fixedSize(horizontal: false, vertical: true)
Run Code Online (Sandbox Code Playgroud)
TextEditor,而不是TextField!)与这里的一些答案相反,正如其他人指出的那样,OP 特别询问了TextEditor,而不是TextField。TextEditor如果您想支持在文本输入期间显式添加换行符,而不仅仅是换行以跨越多行,则需要。
实现这一目标的最简单的解决方案TextEditor需要两件事:
.fixedSize(horizontal: false, vertical: true)on TextEditor (规定绝对最小高度)这是一个例子,我在Button自动增长的正下方有一个TextEditor. 我使用Color.clear无限框架使其贪婪,然后.layoutPriority(1)使其压倒控件的贪婪TextEditor。上面fixedSize写着TextEditor“哟,你不能折叠超过我的文字,布拉!!”,因此这就是它的作用。如果没有fixedSize,它会塌陷到零高度。
struct TestApp: App {
static private let initialText = """
He: Tell me a joke!
She: Ok... what do you call two crows sitting on a branch?
He: I dunno, what?
She: Attempted murder!
"""
@State private var text: String = Self.initialText
var body: some Scene {
WindowGroup {
VStack(alignment: .leading) {
TextEditor(text: $text)
.fixedSize(horizontal: false, vertical: true)
Button("Test Me") {
text = Self.initialText
}
Color.clear
.frame(maxWidth: .infinity, maxHeight: .infinity)
.layoutPriority(1)
}
.padding()
}
}
}
Run Code Online (Sandbox Code Playgroud)
旁注:如上所述,
layoutPriority仅影响当前容器中的布局,因此请确保它所应用的贪婪控件是您的直接兄弟TextEditor(即它们具有相同/直接父级)或位于TextEditor布局的更下方,而不是多于。这也意味着,如果您将下面的控件嵌套
VStack在另一个VStack带有其他控件的控件中,则该外部控件的子控件VStack(包括您的内部控件VStack)将再次在其中均匀分布(当然,除非您layoutPriority也应用到这些控件中的任何一个。)
如上所述,我在那里使用了显式贪婪间隔控件:Color.clear与框架一起使用。但是,从技术上讲,这是不需要的,因为您可以直接向按钮添加框架来实现相同的效果。您只需要还指定适当的alignment值来说明您希望该按钮在框架的贪婪区域中结束的位置。在这里,.topLeading按钮最终位于TextEditor左侧的正下方。如果不添加alignment,按钮将最终位于贪婪区域的中间,这.center是默认对齐方式。
也就是说,我个人更喜欢显式布局,因此间隔符是我的选择,但其他人可能更喜欢不需要专用控件的简单性。*
// `alignment: topLeading` in the frame puts the button in the top-left of the 'greedy' area that the frame creates
Button("Test Me") {
text = Self.initialText
}
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
.layoutPriority(1)
Run Code Online (Sandbox Code Playgroud)
这是结果的示例......
| 归档时间: |
|
| 查看次数: |
13374 次 |
| 最近记录: |