Hacking with iOS: SwiftUI Edition

SwiftUI 布局: ScrollView 使用 Geomet

2020-12-15  本文已影响0人  韦弦Zhy

\color{red}{\Large \mathbf{Hacking \quad with \quad iOS: SwiftUI \quad Edition}}

{\Large \mathbf{GeometryReader}}

当我们使用GeometryReaderframe(in:)方法时,SwiftUI将计算视图在所需坐标空间中的当前位置。但是,随着视图移动,这些值将更改,SwiftUI将自动确保GeometryReader保持更新。

以前我们使用DragGesture将宽度和高度存储为@State属性,因为它允许我们根据拖动量调整其他属性以创建整洁的效果。但是,借助GeometryReader,我们可以动态地从视图环境中获取值,将其绝对或相对位置输入各种修改器中。更好的是,您可以嵌套读取,以便一个可以获取更上层的视图,而另一个可以获取位于该视图下方的内容。

为了说明这一点,我们可以通过在垂直滚动视图中创建50个文本视图来创建旋转螺旋效果,每个文本视图都使用最顶部视图的整个宽度,然后根据其自身位置应用3D旋转效果。

首先制作一个具有不同背景颜色的基本ScrollView文本视图:

struct ContentView: View {
    let colors: [Color] = [.red, .green, .blue, .orange, .pink, .purple, .yellow]

    var body: some View {
        GeometryReader { fullView in
            ScrollView(.vertical) {
                ForEach(0..<50) { index in
                    GeometryReader { geo in
                        Text("Row #\(index)")
                            .font(.title)
                            .frame(width: fullView.size.width)
                            .background(self.colors[index % 7])
                    }
                    .frame(height: 40)
                }
            }
        }
    }
}

要应用螺旋样式的旋转效果,请将以下rotation3DEffect()直接放在background()修饰符下方:

.rotation3DEffect(.degrees(Double(geo.frame(in: .global).minY) / 5), axis: (x: 0, y: 1, z: 0))

当您向下滑动时,您会看到屏幕底部的文本视图被翻转,中心的文本视图旋转了90度,最顶部的文本视图是正常的。更重要的是,当您滚动时,它们都随着滚动视图的移动而旋转。

这是一个很好的效果,但是也有问题,因为视图只有在最顶部时才达到自然方向——很难阅读。为了解决这个问题,我们可以应用更复杂的rotation3DEffect()它减去了主视图高度的一半:

.rotation3DEffect(.degrees(Double(geo.frame(in: .global).minY - fullView.size.height / 2) / 5), axis: (x: 0, y: 1, z: 0))
rotation3DEffect_y/2

将其放置在适当的位置后,视图将在靠近屏幕中心的地方达到自然的方向,看起来会更好。

我们可以使用类似的技术来创建CoverFlow样式的滚动矩形,这次添加一些填充,以便视图自然地位于开始和结束的中心:

struct ContentView: View {
    let colors: [Color] = [.red, .green, .blue, .orange, .pink, .purple, .yellow]

    var body: some View {
        GeometryReader { fullView in
            ScrollView(.horizontal, showsIndicators: false) {
                HStack {
                    ForEach(0..<50) { index in
                        GeometryReader { geo in
                            Rectangle()
                                .fill(self.colors[index % 7])
                                .frame(height: 150)
                                .rotation3DEffect(.degrees(-Double(geo.frame(in: .global).midX - fullView.size.width / 2) / 10), axis: (x: 0, y: 1, z: 0))
                        }
                        .frame(width: 150)
                    }
                }
                .padding(.horizontal, (fullView.size.width - 150) / 2)
            }
        }
        .edgesIgnoringSafeArea(.all)
    }
}
rotation3DEffect_x/2

使用GeometryReader制作特殊效果的方法有很多有趣且富创意的方法——我希望您可以花些时间进行实验!

ScrollView effects using GeometryReader

上一篇下一篇

猜你喜欢

热点阅读