控制SwiftUI中TextEditor的大小

piv4azn7  于 2023-05-21  发布在  Swift
关注(0)|答案(4)|浏览(325)

我想在我的ForEach中有一些TextEditor,我做了这个示例代码!正如您在Image中看到的代码和结果,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!"]
    
}

当前代码结果:

我的目标结果:

vltsax25

vltsax251#

你可以使用一个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()
    }
}

改编自我的另一个答案:Mimicking behavior of iMessage with TextEditor for text entry

xcitsw88

xcitsw882#

iOS 16原生SwiftUI

在iOS 16中,通过添加axis: .vertical.lineLimit(),现在可以原生使用常规的textField
linelimit定义了文本域扩展之前的行数。添加一个范围开始定义一个范围内的行文本字段将开始和停止扩展。

WWDC22会议“SwiftUI中的新功能”17:10左右

r1zhe5dt

r1zhe5dt3#

或者你可以用Form伙计们

struct JustUseAForm: View {
    @State var text1: String = "Enter Text Here"
    @State var text2: String = "Enter Text Here"
    @State var text3: String = "Enter Text Here"

    
    var body: some View {
        Form {
            Group {
                VStack(alignment: .leading) {
                    Spacer(minLength: 8)
                    Text("Comment 1:")
                    TextEditor(text: $text1)
                        .padding(.all, 1.0)
                    
                }
                VStack(alignment: .leading) {
                    Spacer(minLength: 8)
                    Text("Comment 2:")
                    TextEditor(text: $text2)
                        .padding(.all, 1.0)
                }
                VStack(alignment: .leading) {
                    Spacer(minLength: 8)
                    Text("Comment 3:")
                    TextEditor(text: $text3)
                        .padding(.all, 1.0)
                }
            }
            .padding(10)
            .background(Color(.sRGB, red: 0.9, green: 0.9, blue: 0.9, opacity: 0.9))
            .cornerRadius(20)
        }
                    
    }
}

示例:

当然,这意味着你必须接受Forms的默认渲染方式,因为就像.sheet和SwiftUI中的大多数其他东西一样,Apple没有给我们提供自定义外观的方法。你要么喜欢他们给予我们的东西,要么你想出一个奇怪的黑客,或者你 Package 了一个UIKit实现。
有趣的时光。
也许在评论中有人可以为我们解释为什么TextEditor神奇地在Form中正常工作,而在其他地方却不能?或者为什么scaleToFit()不能与TextEditor正常工作?或者为什么lineLimit不能与TextEditor正常工作?问题太多,答案太少,除非你在苹果工作。

t8e9dugd

t8e9dugd4#

添加.fixedSize(horizontal: false, vertical: true)和最小高度为我解决了这个问题。
示例:

TextEditor(text: $myBinding)
           .frame(minHeight: 50)
           .fixedSize(horizontal: false, vertical: true)

相关问题