ios - SwiftUI 中的 anchor

标签 ios swift animation uikit swiftui

我正在玩 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 的中心开始,即 anchor (0.5, 0.5)。有没有办法改变这个 anchor ?我发现我可以在指定 anchor 的 View 上使用 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!")
            }
        }
    }
}

但是好像不完全一样。如果我需要应用多个效果,我应该为每个效果指定 anchor ,而不是只在 View 上指定一次 anchor 。在 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

最佳答案

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

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

父 View 是将内容放在中心的 View ,每次它们的框架发生变化时重新计算其 subview 的位置。

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

另外,请注意 Spacer(),它将 View 向左推。

        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。

如果您有一个复杂的 View (由多个 subview 组成)需要相同的缩放效果,您可以使用 Group{} 将它们分组并在其上使用 .scaleEffect。

关于ios - SwiftUI 中的 anchor ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57442995/

相关文章:

iphone - 当 rootviewcontroller 是 ECSlidingVIewController 时,subview wantsfullscreen 在顶部留下 20px

swift - 将文本字段数据转换为十进制值并返回字符串

ios - Firebase Auth 创建用户

ios - 如何在 iOS 中永远重复动画?

python - 更新 python 动画时删除先前的散点图

ios - UIScrollView 减速过早

objective-c - 反转 UILabel.text 值

Swift 右 CustomColor 类声明

css - 为在 2 点处启动的边框设置动画

ios - 缓慢的 UIViewController 加载时间(缓慢的 ClientState 警告)