如何使用SwiftUI获得ScrollView的动态文本高度

时间:2019-06-30 15:28:43

标签: swift swiftui

这可以给我正确的动态文本高度

import SwiftUI
struct ContentView : View {
    var body: some View {
        GeometryReader { reader in
            ScrollView {
                Text("This is some very long text can we can see scrolls past two lines ")
                    .lineLimit(nil)
                    .frame(width: reader.size.width)
            }
        }
    }
}
#if DEBUG
struct ContentView_Previews : PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
#endif

enter image description here

但是以下内容将文本截断了。如何获得以下动态高度?

public interface MyRepo extends JPARepository<MyObject, Integer>

enter image description here

4 个答案:

答案 0 :(得分:4)

您需要使用fixedSize修饰符来防止截断。在您的情况下,就像:

Text("This is some very long text can we can see scrolls past two lines ")
 .lineLimit(nil)
 .fixedSize(horizontal: false, vertical: true) //** It keeps 'width size' and expands 'height size'
 .frame(width: reader.size.width)

答案 1 :(得分:1)

可能是ScrollView错误。老实说,我不确定为什么您的代码不起作用,但是您可以使用以下方法获得所需的结果:

struct ContentView : View {
    var body: some View {
        GeometryReader { reader in
            ScrollView(alwaysBounceVertical: true) {
                ZStack(alignment: .top) {
                    Color.clear.edgesIgnoringSafeArea(.all)
                    Text("This is some very long text can we can see scrolls past two lines ")
                        .lineLimit(nil)
                }.frame(width: reader.size.width, height: reader.size.height)
            }
        }
    }
}

我在滚动视图中添加了alwaysBounceVertical,因此您可以看到该视图在滚动。没必要。

答案 2 :(得分:0)

我认为这是一个错误,因为我无法找到其行为的原理。

让我解释一下:

如果没有ScrollView,我们知道将Text视图的宽度强制为特定宽度并使用lineLimit(nil)将使文本视图垂直扩展以容纳文本。相反,如果您具有lineLimit(1),则将显示省略号以截断视图的内容。

现在,如果我们在ScrollView中包含Text(),并且将宽度强制设置为特定大小并设置lineLimit(nil),则会有两个可接受的结果:

  1. 文本视图遵循新宽度并垂直扩展。
  2. 文本视图不考虑宽度,但允许您水平滚动。根本不是一个好的选择,但这可能是由谁开发框架决定的。

但是,实际上发生的是,文本视图遵循新的宽度大小(由省略号表明),但是尽管lineLimit(nil)仍然不会垂直扩展。没有理由这样做,因为通过使用lineLimit(1)已经可以实现该行为。这就是为什么我认为这绝对是一个错误。

您应该向Apple提交错误报告。

答案 3 :(得分:0)

import SwiftUI

struct ContentView : View {

    let veryLongText = "Very long text..."
    let fontName = "System Font"
    let fontSize: Length = 12

    var body: some View {
        GeometryReader { geometry in
            ScrollView {
                Text(veryLongText)
                    .lineLimit(nil)
                    .font(.custom(fontName, size: fontSize))
                    .frame(width: geometry.size.width, height: veryLongText.textHeightFrom(width: geometry.size.width, fontName: fontName, fontSize: fontSize))
            }
        }
        .padding(.horizontal, 0.5 * fontSize)
    }
}

extension String {

    func textHeightFrom(width: CGFloat, fontName: String = "System Font", fontSize: CGFloat = .systemFontSize) -> CGFloat {

        #if os(macOS) 

        typealias UXFont = NSFont
        let text: NSTextField = .init(string: self)
        text.font = NSFont.init(name: fontName, size: fontSize)

        #else

        typealias UXFont = UIFont
        let text: UILabel = .init()
        text.text = self
        text.numberOfLines = 0

        #endif

        text.font = UXFont.init(name: fontName, size: fontSize)
        text.lineBreakMode = .byWordWrapping
        return text.sizeThatFits(CGSize.init(width: width, height: .infinity)).height
    }
}