SwiftUI 中的锚点

Posted

技术标签:

【中文标题】SwiftUI 中的锚点【英文标题】:Anchor point in SwiftUI 【发布时间】:2019-08-10 14:27:45 【问题描述】:

我正在玩SwiftUI 动画。我想用这种方式用动画修改它的框架来做一个更大的正方形:

struct ContentView: View 
    let squareWidth = CGFloat(100)
    let squareHeight = CGFloat(100)

    @State private var bigger = false

    var body: some View 
        VStack 
            Color.green
                .frame(width: bigger ? self.squareWidth * 2 : self.squareWidth, height: self.squareHeight)
                .animation(.default)
            Button(action: 
                    self.bigger.toggle()
            ) 
                Text("Click me!")
            
        
    

动画从 View 的中心发生,即锚点 (0.5, 0.5)。有没有办法改变这个锚点?我发现我可以在指定anchor 的视图上使用scaleEffect

struct ContentView: View 
    let squareWidth = CGFloat(100)
    let squareHeight = CGFloat(100)

    @State private var bigger = false

    var body: some View 
        VStack 
            Color.green
                .frame(width: self.squareWidth, height: self.squareHeight)
                .scaleEffect(x: bigger ? 2 : 1, y: 1, anchor: .leading)
                .animation(.default)
            Button(action: 
                    self.bigger.toggle()
            ) 
                Text("Click me!")
            
        
    

但看起来并不完全相同。如果我需要应用多个效果,我应该为每个效果指定锚点,而不是一次在视图上指定锚点。在UIKit 我可以写:

var myView = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
myView.layer.anchorPoint = CGPoint(x: 0, y: 0.5) //that is, the .leading of SwiftUI

【问题讨论】:

我不知道是否有更改动画锚点的选项,但是通过添加填充可以更改动画的中心。我在.animation(.default)之后尝试了.padding(.leading, bigger ? self.squareWidth : 0 )您的Color.green 视图。如果这不能解决您的问题,请更具体地了解应用多种效果 【参考方案1】:

这是可能的,但你的方法必须改变。

在 SwiftUI 中有一个隐含的、内置的视图居中,这可能会造成混淆。

父视图是将内容置于中心的视图,每次其子视图的帧发生变化时,都会重新计算其位置。

将 VStack 嵌入 HStack 并为两者添加边框清楚地显示了这种行为。

另外,请注意Spacer(),它将视图推向左侧。

        HStack 
            VStack 
                Color.green
                    .frame(width: bigger ? self.squareWidth * 2 : self.squareWidth)
                    .frame(height: self.squareHeight)
                    .animation(.default)

                Button("Click me!")  self.bigger.toggle() 
            .border(Color.black)

            Spacer()

        .border(Color.red)

在 UIKit 中使用 .layer.anchorPoint 应该与在 SwiftUI 中使用 scaleEffect/offset/rotationEffect 具有相同的效果,因为它应该会影响 GPU 正在渲染的底层几何体/纹理的原点。

如果您有一个复杂的视图(由多个子视图组成)需要相同的缩放效果,您可以使用Group 对它们进行分组并在其上使用 .scaleEffect。

【讨论】:

谢谢。我现在知道了。是的,正如你所说,这种内置的视图中心有点令人困惑,你的例子很清楚。

以上是关于SwiftUI 中的锚点的主要内容,如果未能解决你的问题,请参考以下文章

链接中的锚点

Delphi XE2:跳到 CHM 中的锚点?

替换文本中的锚点/链接

HTML中的锚点以及锚点的设置与应用

如何判断页面是不是已跳转到 javascript 中的锚点 (#)?

去掉浏览器中的锚点#号