【问题标题】:SwiftUI text field orphan on macOSmacOS 上的 SwiftUI 文本字段孤儿
【发布时间】:2022-06-21 15:05:44
【问题描述】:

我有一个这样的文本字段

Text("Hello, one two three four five six seven eight!")
                .frame(width:270)
                .border(.blue)

当它渲染时,它决定将七和八放在第二行,即使第一行有七的空间。更糟糕的是,它决定缩进截断的顶行,使其在框架内居中。

如何解决此问题,以便在不考虑孤儿的情况下正确包装文本?

编辑:忘了提到我想要在 macOS 上使用它。我试图将它移植到 Mac 上。它确实正确地左对齐文本,但它不会换行到第二行。不过,盒子的高度确实会相应地计算出来。

这是我更新的代码:

struct NonOrphanedText: View
{
    var text: String
    
    @State private var height: CGFloat = .zero
    
    var body: some View
    {
        InternalLabelView(text: text, dynamicHeight: $height)
            .frame(maxHeight: height)
    }
    
    struct InternalLabelView: NSViewRepresentable
    {
        var text: String
        @Binding var dynamicHeight: CGFloat
        
        func makeNSView(context: Context) -> NSTextField
        {
            let label = NSTextField()
            label.isEditable = false
            label.isBezeled = false
            label.drawsBackground = false
            label.isSelectable = false
            label.maximumNumberOfLines = 5
            label.usesSingleLineMode = false
            label.lineBreakStrategy = .init()
            label.lineBreakMode = .byWordWrapping
            label.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
            return label
        }
        
        func updateNSView(_ nsView: NSTextField, context: Context)
        {
            nsView.stringValue = text
            
            DispatchQueue.main.async
            {
                dynamicHeight = nsView.sizeThatFits(CGSize(width: nsView.bounds.width, height: CGFloat.greatestFiniteMagnitude)).height
            }
        }
    }
}

【问题讨论】:

    标签: macos text swiftui


    【解决方案1】:

    我们需要lineBreakStrategy,但它目前在 SwiftUI 中不可用,因此可能的解决方案是使用 UILabel

    这是一个可能的解决方案。使用 Xcode 13.2 / iOS 15.2 测试

    struct LabelView: View {
        var text: String
    
        @State private var height: CGFloat = .zero
    
        var body: some View {
            InternalLabelView(text: text, dynamicHeight: $height)
                .frame(maxHeight: height)
        }
    
        struct InternalLabelView: UIViewRepresentable {
            var text: String
            @Binding var dynamicHeight: CGFloat
    
            func makeUIView(context: Context) -> UILabel {
                let label = UILabel()
                label.numberOfLines = 0
                label.lineBreakStrategy = .init()          // << here !!
                label.lineBreakMode = .byWordWrapping
                label.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
    
                return label
            }
    
            func updateUIView(_ uiView: UILabel, context: Context) {
                uiView.text = text
    
                DispatchQueue.main.async {
                    dynamicHeight = uiView.sizeThatFits(CGSize(width: uiView.bounds.width, height: CGFloat.greatestFiniteMagnitude)).height
                }
            }
        }
    }
    

    backup

    【讨论】:

    • 这很好用,但我忘了提到我想要在 macOS 上使用它。我试图将它移植到 Mac 上。它确实正确地左对齐文本,但它不会换行到第二行。盒子的高度确实得到了相应的计算。谢谢
    猜你喜欢
    • 1970-01-01
    • 2018-10-05
    • 2019-12-31
    • 2020-12-24
    • 2020-05-26
    • 2020-07-02
    • 2011-01-02
    • 2019-02-03
    • 2012-10-22
    相关资源
    最近更新 更多