【问题标题】:Dynamic row hight containing TextEditor inside a List in SwiftUISwiftUI 列表中包含文本编辑器的动态行高
【发布时间】:2020-10-18 13:58:54
【问题描述】:

我有一个 List 包含一个 TextEditor

struct ContentView: View {
    @State var text: String = "test"

    var body: some View {
        List((1...10), id: \.self) { _ in
            TextEditor(text: $text)
        }
    }
}

但它的项目并没有随着TextEditor 的高度变化而增长。我试过 .fixedSize() 修饰符但没有运气。我在这里错过了什么?

【问题讨论】:

    标签: swift swiftui


    【解决方案1】:

    据我从视图层次结构中看到,TextEditor 只是UITextView 的简单包装,没有更多要添加的内容,因此您可以深入该层并找到满足您需要的 UIKit 解决方案,或者.. .

    这里是在 SwiftUI 级别处理它的可能方法的演示(想法是使用 Text 视图作为包装行为的参考,并精确调整 TextEditor

    使用 Xcode 12b / iOS 14 测试(添加红色边框以提高可见性)

    修改了你的观点:

    struct ContentView: View {
        @State var text: String = "test"
    
        @State private var height: CGFloat = .zero
        var body: some View {
            List {
                ForEach((1...10), id: \.self) { _ in
                    ZStack(alignment: .leading) {
                        Text(text).foregroundColor(.clear).padding(6)
                            .background(GeometryReader {
                                Color.clear.preference(key: ViewHeightKey.self, value: $0.frame(in: .local).size.height)
                            })
                        TextEditor(text: $text)
                            .frame(minHeight: height)
                            //.border(Color.red)        // << for testing
                    }
                    .onPreferenceChange(ViewHeightKey.self) { height = $0 }
                }
            }
        }
    }
    

    注意:ViewHeightKey 是一个偏好键,在我的其他解决方案中使用,所以可以从那里获取

    ForEach and GeometryReader: variable height for children?

    How to make a SwiftUI List scroll automatically?

    Automatically adjustable view height based on text height in SwiftUI

    【讨论】:

    • 这种方法在List 中效果很好,但在带有VStackScrollView 中似乎不起作用。你有没有偶然尝试过这种方式?
    • 如果不使用 List,可以使用 .fixedSize(horizo​​ntal: false, vertical: true)。
    【解决方案2】:

    您可以在ZStack 中使用不可见的Text 使其动态化。

    struct ContentView: View {
        @State var text: String = "test"
    
        var body: some View {
            List((1...10), id: \.self) { _ in
                ZStack {
                    TextEditor(text: $text)
                    Text(text).opacity(0).padding(.all, 8) // <- This will solve the issue if it is in the same ZStack
                }
            }
        }
    }
    

    请注意,您应该考虑更改字体大小和其他属性以匹配TextEditor

    【讨论】:

    • 我必须将 Text 标签放在 ZStack 中的 TextEditor 之前。另外为了确保滚动条不会出现,我不得不将 ZStack 放在 HStack 中。
    • 在editMode下也不起作用。我不得不通过创建 + 和 - 圈来伪造它
    • 在实现此方法时在 iOS 14.4 中,TextEditor 最初有一个滚动条,并且只显示一行文本。如果我编辑文本,列表行会扩展以适应内容,TextEditor 的滚动条会消失。看起来很麻烦。
    猜你喜欢
    • 2020-02-27
    • 1970-01-01
    • 2021-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-25
    相关资源
    最近更新 更多