ScrollView 固定高度基于内容

huangapple go评论52阅读模式
英文:

ScrollView fixed height based content

问题

  1. 我正在使用 ScrollView 来管理我的 View 中文本的显示。

  2. 当文本非常长时,ScrollView 应根据文本的大小进行拉伸。我该如何做到这一点?

  3. 我尝试了一些方法,您可以在我的示例中看到。

  4. 此外,当文本不长时,我需要使 ScrollView 无法滚动。我该如何解决这两个问题?

struct Test2: View {
    @State private var contentSize: CGSize = .zero

    var body: some View {
        ZStack {
            Color.blue
                .ignoresSafeArea()
            VStack {
                ScrollView {
                    Text("这是一个测试文本这是一个测试文本这是一个测试文本这是一个测试")
                        .padding()
                        .overlay {
                            GeometryReader { geo in
                                Color.clear.onAppear {
                                    contentSize = geo.size
                                }
                            }
                        }
                }
            }
            .background(.white)
            .frame(maxHeight: contentSize.height)
        }
    }
}

请注意,我已经将文本翻译为中文,但代码部分没有进行翻译。

英文:

I'm working with a ScrollView to manage the display of a text in my View.

  1. When the text is very long the ScrollView should stretch according to the Text. How can I do this?

I tried a few attempts which you can see here in my example.

  1. Also I need the ScrollView to be non-scrollable when the text is not long. How can I solve these two problems?

struct Test2: View {   
    @State private var contentSize: CGSize = .zero

    var body: some View {
        
        ZStack {
            Color.blue
                .ignoresSafeArea()
                VStack {
                    ScrollView {
                        Text ("This is a test textThis is a test texThis is a test texThis is a test")
                            .padding()
                            .overlay {
                                GeometryReader { geo in
                                    Color.clear.onAppear {
                                        contentSize = geo.size
                                    }
                                }
                            }
                    }
                }
                .background(.white)
                .frame(maxHeight: contentSize.height)
        }
    }
}

答案1

得分: 1

以下是翻译好的内容:

  1. The ScrollView已经似乎会在出现时自动调整大小以适应文本,但如果需要在出现后更改文本内容,请尝试在GeometryReader中添加以下内容以在更改时更新大小:

    Color.clear.onChange(of: text) {
        newText in
        contentSize = geo.size
    }
    

    不过,你需要一个变量来存储文本内容。

    @State private var text: String = "This is a test textThis is a test texThis is a test texThis is a test"
    

    (将Text("This is...")替换为Text(text)

  2. 这可能不是最高效的方法,但你可以为scrollDisabled添加一个变量,以便在文本更改/出现时更新它。

    contentSize下面添加:

    @State private var cantScroll: Bool = true
    

    将ZStack嵌套在GeometryReader中(GeometryReader { viewGeo in...),然后在每次contentSize更新时添加代码来检查和比较视图大小:

    if contentSize.height > viewGeo.size.height {
        cantScroll = false
    } else {
        cantScroll = true
    }
    

    最后,修改ScrollView:

    .scrollDisabled(cantScroll)
    

    最终的代码:

    struct Test2: View {
        @State private var contentSize: CGSize = .zero
        @State private var text: String = "This is a test textThis is a test texThis is a test texThis is a test"
        @State private var cantScroll: Bool = true
    
        var body: some View {
            GeometryReader { viewGeo in
                ZStack {
                    Color.blue
                        .ignoresSafeArea()
                    VStack {
                        ScrollView {
                            Text(text)
                                .padding()
                                .overlay {
                                    GeometryReader { geo in
                                        Color.clear.onAppear {
                                            contentSize = geo.size
                                            if contentSize.height > viewGeo.size.height {
                                                cantScroll = false
                                            } else {
                                                cantScroll = true
                                            }
                                        }
                                        Color.clear.onChange(of: text) {
                                            _ in
                                            contentSize = geo.size
                                            if contentSize.height > viewGeo.size.height {
                                                cantScroll = false
                                            } else {
                                                cantScroll = true
                                            }
                                        }
                                    }
                                }
                        }
                        .scrollDisabled(cantScroll)
                    }
                    .background(.white)
                    .frame(maxHeight: contentSize.height)
                }
            }
        }
    }
    

希望这对你有所帮助。

英文:
  1. The ScrollView already seems to resize to fit the text when it appears, but if you need to change the text content after it appears, try adding this in the GeometryReader to update the size when it changes:

     Color.clear.onChange(of: text) {
         newText in
         contentSize = geo.size
     }
    

You would need a variable for the text though.

    @State private var text: String = "This is a test textThis is a test texThis is a test texThis is a test" 

(replace Text("This is...") with Text(text))

  1. It's probably not the most efficient way, but you can have a variable for scrollDisabled that updates when the text changes/appears.

Underneath contentSize:

@State private var cantScroll: Bool = true

Embed ZStack in GeometryReader (GeometryReader { viewGeo in...), then
add code to check and compare view sizes whenever contentSize updates:

if contentSize.height > viewGeo.size.height {
    cantScroll = false
} else {
    cantScroll = true
}

And finally, modify ScrollView:

.scrollDisabled(cantScroll)

Final code:

struct Test2: View {
    @State private var contentSize: CGSize = .zero
    @State private var text: String = "This is a test textThis is a test texThis is a test texThis is a test"
    @State private var cantScroll: Bool = true

    var body: some View {
        GeometryReader { viewGeo in
            ZStack {
                Color.blue
                    .ignoresSafeArea()
                VStack {
                    ScrollView {
                        Text(text)
                            .padding()
                            .overlay {
                                GeometryReader { geo in
                                    Color.clear.onAppear {
                                        contentSize = geo.size
                                        if contentSize.height > viewGeo.size.height {
                                            cantScroll = false
                                        } else {
                                            cantScroll = true
                                        }
                                    }
                                    Color.clear.onChange(of: text) {
                                        _ in
                                        contentSize = geo.size
                                        if contentSize.height > viewGeo.size.height {
                                            cantScroll = false
                                        } else {
                                            cantScroll = true
                                        }
                                    }
                                }
                            }
                    }
                    .scrollDisabled(cantScroll)
                }
                .background(.white)
                .frame(maxHeight: contentSize.height)
            }
        }
    }
}

I hope this helps.

huangapple
  • 本文由 发表于 2023年5月8日 02:36:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/76195668-2.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定