动画约束导致不同的初始位置
Posted
技术标签:
【中文标题】动画约束导致不同的初始位置【英文标题】:Animating constraint results in different initial position 【发布时间】:2017-06-23 11:45:39 【问题描述】:我有一个绿色视图,它固定在顶视图的边缘。顶部是一个蓝色视图,它也是顶视图的子视图,使用以下代码对齐...
import UIKit
class ViewController: UIViewController
@IBOutlet weak var blueView: UIView!
@IBOutlet weak var greenView: UIView!
override func viewDidLoad()
super.viewDidLoad()
blueView.translatesAutoresizingMaskIntoConstraints = false
blueView.widthAnchor.constraint(equalTo: greenView.widthAnchor).isActive = true
blueView.leftAnchor.constraint(equalTo: greenView.leftAnchor).isActive = true
blueView.heightAnchor.constraint(equalTo: greenView.heightAnchor).isActive = true
let top = blueView.topAnchor.constraint(equalTo: greenView.topAnchor)
top.priority = 800
top.isActive = true
view.layoutIfNeeded()
UIView.animate(withDuration: 5)
let bottom = self.blueView.topAnchor.constraint(equalTo: self.greenView.bottomAnchor)
bottom.priority = 1000
bottom.isActive = true
self.view.layoutIfNeeded()
如果我把动画代码注释掉,就是这个样子……
使用动画块,蓝色视图在正确的位置结束,但它从屏幕顶部开始,而不是与绿色视图的顶部对齐。
为什么动画块会导致蓝色视图在屏幕上进一步启动?
【问题讨论】:
根据您的代码,您将Blue
设置为与Green
相同的大小和位置......然后动画块向下滑动Blue
直到它完全离开屏幕。这就是你所看到的吗?这不是你想要的吗?
这就是我想要的,主要是它在做什么。问题是动画似乎导致蓝色从屏幕顶部开始,而不是在与绿色相同的位置。
【参考方案1】:
好的 - 蓝色视图没有从绿色视图的顶部开始,因为您在初始布局完成之前开始动画。
您可以将动画块移动到延迟后触发的函数中,或移动到viewDidAppear
:
import UIKit
class AnimViewController: UIViewController
@IBOutlet weak var blueView: UIView!
@IBOutlet weak var greenView: UIView!
override func viewDidLoad()
super.viewDidLoad()
blueView.translatesAutoresizingMaskIntoConstraints = false
blueView.widthAnchor.constraint(equalTo: greenView.widthAnchor).isActive = true
blueView.leftAnchor.constraint(equalTo: greenView.leftAnchor).isActive = true
blueView.heightAnchor.constraint(equalTo: greenView.heightAnchor).isActive = true
let top = blueView.topAnchor.constraint(equalTo: greenView.topAnchor)
top.priority = 800
top.isActive = true
override func viewDidAppear(_ animated: Bool)
super.viewDidAppear(animated)
UIView.animate(withDuration: 5)
let bottom = self.blueView.topAnchor.constraint(equalTo: self.greenView.bottomAnchor)
bottom.priority = 1000
bottom.isActive = true
self.view.layoutIfNeeded()
【讨论】:
没有办法在开始动画之前强制更新吗?viewDidLoad
在视图控制器的活动顺序中非常早。 viewDidAppear
是一个非常适合开始 5 秒动画的地方。
例如,如果您想将所有这些代码放在点击处理程序上怎么办?您是在暗示需要添加延迟?
不...当您加载并显示视图控制器时,必须发生很多事情。 viewDidLoad
在过程中早期,子视图、手势、约束等还没有被操作系统完全“解决”。你有 viewDidLoad
viewWillAppear
viewWillLayoutSubviews
viewDidLayoutSubviews
viewDidAppear
等等。对按钮点击采取行动是完全不同的情况 - 你正在对已经存在的对象进行操作(除非你的意思是按钮点击加载一个新的控制器, 在这种情况下,请参阅以前的 cmets)。
是的,动态添加的视图控制器的动画问题正是导致问题的原因。抱歉,您指的是以前的哪些 cmets?以上是关于动画约束导致不同的初始位置的主要内容,如果未能解决你的问题,请参考以下文章
动画 UITableView 的自动布局顶部约束导致崩溃,有啥线索吗?