带有渐变的SwiftUI ScrollView文本

Posted

技术标签:

【中文标题】带有渐变的SwiftUI ScrollView文本【英文标题】:SwiftUI ScrollView Text with gradient 【发布时间】:2020-07-22 17:05:41 【问题描述】:

我正在尝试实现一个视图,其中我有一个长文本并且文本通过拖动手势滚动。 (滚动视图)。我试图实现的技巧是要有一个渐变,所以在 to 和 Botton 的文本应该有一种不透明度:

我可以使用 ZStack 和质量渐变来做到这一点,但是一旦我将矩形移到我的文本上,来自 ScrollView 的滚动就不再起作用了。

这是我想要做的动画版本:https://media.giphy.com/media/j3bXQOV1vZMxZS6GAk/giphy.gif

这是我的代码:

struct ContentView: View 
    var body: some View 
        GeometryReader  fullView in
            ZStack 
                ScrollView() 
                    Text("Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.")
                
                
                LinearGradient(gradient: Gradient(colors: [.white, .clear,.clear, .white]), startPoint: .top, endPoint: .bottom)
                    .mask(
                        Rectangle()
                )
            
        
    

你们有这样的需求吗?

感谢和问候, 最大

【问题讨论】:

【参考方案1】:

是的,我实际上想这样做一次,但我从来没有做过。但是,查看您的代码,您可能会执行以下操作:

//useful for testing large text blocks
func * (lhs: Text, rhs: Int) -> Text 
    var out = lhs
    for _ in 0..<rhs  out = out + lhs 
    return out

struct ContentView: View 
    var body: some View 
        //first geometry reader, used to determine the _size_ of the gradient
        GeometryReader  fullView in
            ScrollView() 
                ZStack
                    Text("Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt.") * 60
                    //second geometry reader, used to determin the _offset_ of the gradient
                    GeometryReader geo in
                        LinearGradient(gradient:
                            Gradient(colors: [
                                .white,
                                .clear,
                                .clear,
                                .white
                            ]), startPoint: .top, endPoint: .bottom)
                            .mask( Rectangle() )
                            .frame(width: fullView.size.width, height: fullView.size.height)
                            .offset(x: 0, y: -geo.frame(in: .global).origin.y)
                    
                
                
            
        
        .edgesIgnoringSafeArea(.all)
    

这里发生的事情是我们使用fullview Geometry Reader 设置线性渐变的大小,并且我们根据geo Geometry Reader 的框架设置偏移量,两个几何读取器的位置在视图“层次结构”很重要。


另外,我想指出,您的渐变在某些地方看起来有点暗... 通过查看代码,这可能不是您打算做的。发生这种情况是因为 Color.clear 实际上是一个 0,0,0 的 rgb 值,alpha 为 0。所以当颜色被插值时,它会变成黑色或灰色。

您可以通过将.clear 替换为:

.init(UIColor(red: 1, green: 1, blue: 1, alpha: 0))

这是一个截图,我将顶部颜色设置为.init(UIColor(red: 1, green: 1, blue: 1, alpha: 0)),底部颜色设置为.clear

【讨论】:

嘿塞缪尔,我喜欢你的解决方案。这与我们想要达到的目标非常接近。如果我使用整个屏幕,代码效果很好。但是,如果我放置一些框架来限制滚动的大小,渐变接缝就不会在正确的位置。

以上是关于带有渐变的SwiftUI ScrollView文本的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI - tvOS 上的列表 - 顶部渐变

当嵌入到 SwiftUI 中的 ScrollView 中时,VStack 内的内容会缩小

SwiftUI:在 ScrollView 或 List 中时,PageTabViewStyle() 新损坏?

带有 ScrollView 外观的 SwiftUI 错误

ScrollView 文本对齐 SwiftUI

SwiftUI:在 ScrollView 中显示 HTML 文本