SwiftUI中包含TextEditor的动态行高列表

14

我有一个包含 TextEditorList

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

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

但是当的高度发生变化时,其项目并没有增长。我已经尝试使用.fixedSize()修饰符,但没有成功。我在这里漏掉了什么?

2个回答

32
您可以使用一个不可见的TextZStack中使其动态。
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

预览


2
我不得不在ZStack中的TextEditor之前放置Text标签。为了确保滚动条不出现,我还必须将ZStack放在HStack中。 - ngb
同时它在编辑模式下不起作用。我不得不通过创建“+”和“-”圆圈来模拟它。 - ngb
1
在 iOS 14.4 中实现这种方法时,TextEditor 最初具有滚动条,并且只显示一行文本。如果我编辑文本,则列表行扩展以适应内容并隐藏 TextEditor 的滚动条。看起来非常有 bug。 - Clifton Labrum

10

就我所见,从视图层次结构来看,TextEditor只是一个简单的UITextView包装器,并没有更多的添加,因此您可以进入该层并找到UIKit解决方案以满足您的需求,或者...

这里是可能处理它在SwiftUI级别的示例(思路是使用Text视图作为包装行为的参考,并将TextEditor调整为与之完全一致)

在Xcode 12b / iOS 14下测试(为了更好的可见性添加了红色边框)

demo

修改了您的视图:

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 和 GeometryReader:子视图的可变高度?

如何使 SwiftUI 列表自动滚动?

基于文本高度自动调整视图高度在 SwiftUI 中


这种方法在List中非常有效,但在带有VStackScrollView中似乎不起作用。你碰巧尝试过这样做吗? - Clifton Labrum
2
如果您没有使用List,可以使用.fixedSize(horizontal: false, vertical: true)。 - Tarek Hallak
@TarekHallak 这个建议太好了!我们需要这个来使其工作。对于任何需要的人,我们在 Text 上使用了 .fixedSize,而不是 TextEditor。但是,为什么这样会起作用呢? - James Toomey
不幸的是,TextEditor 的高度与 Text 不同。需要添加大约10来禁用TextEditor内部滚动。虽然这在几行中可能看不到! - kelalaka
很遗憾,TextEditor的高度与Text不一样。需要添加大约10个来禁用TextEditor的内部滚动。虽然在几行中可能看不到这个问题! - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接