视图框架的 UIView.animate 问题

Posted

技术标签:

【中文标题】视图框架的 UIView.animate 问题【英文标题】:UIView.animate problems with view frame 【发布时间】:2017-09-28 15:21:16 【问题描述】:

我正在努力制作动画。这就是正在发生的事情:video

后面的卡片应该做与视频开头相同的动画,但它做的是完全不同的事情。我在查看动画开始时的UIView.frame,和第一次进卡时一样,但显然有问题……下面是代码:

func cardIn() 
    let xPosition = (self.darkCardView?.frame.origin.x)! - 300
    let yPosition = (self.darkCardView?.frame.origin.y)!

    self.initialPos = self.darkCardView.frame

    let height = self.darkCardView?.frame.size.height
    let width = self.darkCardView?.frame.size.width

    self.darkCardView?.transform = (self.darkCardImageView?.transform.rotated(by: CGFloat(Double.pi/4)))!

    UIView.animate(withDuration: 1.1, animations: 
        self.darkCardView?.frame = CGRect(x: xPosition, y: yPosition, width: width!, height: height!)
        self.darkCardView?.transform = (self.darkCardImageView?.transform.rotated(by: CGFloat(0)))!
    )


func cardOut() 
    let xPosition = (self.darkCardView?.frame.origin.x)! - 600
    let yPosition = (self.darkCardView?.frame.origin.y)!

    let height = self.darkCardView?.frame.size.height
    let width = self.darkCardView?.frame.size.width

    self.darkCardView?.transform = (self.darkCardImageView?.transform.rotated(by: CGFloat(0)))!

    UIView.animate(withDuration: 1.0, delay: 0, options: .allowAnimatedContent, animations: 
        self.darkCardView?.frame = CGRect(x: xPosition, y: yPosition, width: width!, height: height!)
        self.darkCardView?.transform = (self.darkCardImageView?.transform.rotated(by: CGFloat(-Double.pi/4)))!
    )  (true) in
        self.darkCardView?.transform = (self.darkCardImageView?.transform.rotated(by: CGFloat(0)))!
        self.darkCardView?.frame = self.initialPos

        self.cardIn()
    

有人知道如何在调用 cardOut 函数后重复视频开头的相同动画吗?

【问题讨论】:

看看这个***.com/questions/27660540/… 你在使用自动布局吗? @Jerland2,不,我没有使用自动布局。我应该吗? 【参考方案1】:

鉴于我们不知道您在何处/何时调用上述两个函数,我只能猜测发生了什么。

所以你有一个动画输入和一个动画输出,但是重置功能呢?

时间线: 动画卡进去。 ... 最终将卡片制作成动画 ... 将卡片位置重置为右侧的屏幕外(第一次制作动画之前的位置) ... 为卡片制作动画 ... 重复,等等......

【讨论】:

我将卡片“重置”到其在 cardOut 的完成块中的初始位置。我使用了这两行代码:self.darkCardView?.transform = (self.darkCardImageView?.transform.rotated(by: CGFloat(0)))! self.darkCardView?.frame = self.initialPos 我再次将角度设置回 0,这个 initialPos 是我在 viewDidLoad 中创建的一个变量,它采用了背卡【参考方案2】:

我设法通过在结束 o cardOut 完成块中调用 viewDidLoad() 而不是调用 self.cardIn() 来解决动画问题。但我不想依赖每次新卡必须进入屏幕时调用 viewDidLoad...

另外,我没有在 viewDidLoad 中设置背卡的任何属性。我只在 .xib 文件中有它。有什么想法吗?

【讨论】:

【参考方案3】:

请注意,如果您将视图的变换设置为身份变换以外的任何内容,则视图的框架矩形将变为“未定义”。您既不能将其设置为新值,也不能可靠地读取它的值。

如果要更改转换,则应更改代码以使用视图的中心属性。

正如 Jerland 在他们的帖子中指出的那样,您可能还需要在开始下一个动画循环之前将您的背卡重置为其起始位置。 (将其设置为隐藏,将其中心放回起始位置并将其变换设置回身份变换。

编辑:

这段代码:

UIView.animate(withDuration: 1.0, delay: 0, options: .allowAnimatedContent, animations: 
    self.darkCardView?.frame = CGRect(x: xPosition, y: yPosition, width: width!, height: height!)
    self.darkCardView?.transform = (self.darkCardImageView?.transform.rotated(by: CGFloat(-Double.pi/4)))!
)  (true) in
    self.darkCardView?.transform = (self.darkCardImageView?.transform.rotated(by: CGFloat(0)))!
    self.darkCardView?.frame = self.initialPos

    self.cardIn()

不将转换设置为身份。尝试将该行更改为

    self.darkCardView?.transform = .identity

【讨论】:

我试过检查卡的中心,如你所说。但cardOut 末尾的中心与cardIn 开头的中心相同。正如你和Jerland所说,我也重置了卡,但我已经在cardOut的完成中完成了,这就是代码没有重置功能的原因。 做到了,你是对的。事实上,它并没有设置为它的身份转换。虽然,它并没有解决动画的问题......我添加了一个新的答案,我说只需将对 self.cardIn() 函数的调用更改为 self.viewDidLoad() 就足以让动画按预期运行,但我仍然不知道为什么这解决了我的问题...

以上是关于视图框架的 UIView.animate 问题的主要内容,如果未能解决你的问题,请参考以下文章

UIView 框架的 CASpringAnimation

UIView.animate() 无法为视图设置动画的各种原因都有哪些?

当使用 UIView.animate 动画视图时,其他视图也不需要动画

UIView.animate 在 UIPanGestureRecognizer 中时在框架上

UIView.animate 不在一个功能上制作动画

UIView.animate 没有完美地动画布尔值