首页 > 解决方案 > SwiftUI 列表包含 Mac 上自动换行的文本

问题描述

我在 Mac 上遇到了包含文本行的列表的问题,这些文本行包含换行的文本。

这是代码:

struct ContentView: View {
    var messages = [
        "This is a long piece of text that's going to need to be wrapped to fit into the view.",
        "This is another long piece of text that's going to need to be wrapped to fit into the view."
    ]

    var body: some View {
        List(messages, id: \.self) { message in
            Text(message)
                .lineLimit(nil)
                .border(Color.blue)
                .fixedSize(horizontal: false, vertical: true)

                // Also tried .fixedSize(horizontal: true, vertical: false)
                // which seems more correct, but doesn't wrap the text at all
        }.frame(maxWidth: .infinity, maxHeight: .infinity)
    }
}

当我在 iOS 上运行它时,结果是我所期望的:

复制电话

然而,在 Mac 上,SwiftUI 正在创建的基础表似乎没有调整行高以适应包装的内容:

Repro-Mac

我已将此报告为错误(FB7421021),但在这里询问以防其他人为此苦苦挣扎。

谢谢

标签: macosswiftui

解决方案


这是从对我有用的类似用例中采用的方法。希望它对其他人有用。

struct TestWrappedText: View {
    var messages = [
        "This is a long piece of text that's going to need to be wrapped to fit into the view.",
        "This is another long piece of text that's going to need to be wrapped to fit into the view."
    ]

    @State var alignedHeight: [CGFloat] = [0, 0]

    var body: some View {
        List(0 ..< messages.count) { i in
            Text(self.messages[i])
                .border(Color.blue)
                .fixedSize(horizontal: false, vertical: true)
                .modifier(ViewHeightKey())
                .onPreferenceChange(ViewHeightKey.self) {
                    if self.alignedHeight[i] != $0 {
                        self.alignedHeight[i] = $0
                    }
                }
                .frame(height: self.alignedHeight[i])
        }
    }
}

struct ViewHeightKey: PreferenceKey {
    static var defaultValue: CGFloat { 0 }
    static func reduce(value: inout Value, nextValue: () -> Value) {
        value = nextValue()
    }
}

extension ViewHeightKey: ViewModifier {
    func body(content: Content) -> some View {
        return content.background(GeometryReader { proxy in
            Color.clear.preference(key: Self.self, value: proxy.size.height)
        })
    }
}

推荐阅读