你想要的其实相当简单,我会详细说明如何完成它,而不会影响优先级或奇怪的常量。这样我们就可以得到一个在任何屏幕大小上都能工作的动画。
简短版本是,你需要配置约束,并在动画块内调用layoutIfNeeded以动画化更改。欲了解更多,请参见此
SO帖子。
因此,我们需要两组用于隐藏和显示视图的约束。在viewDidLoad中,视图将被隐藏,然后在viewDidAppear或任何我们想要滑入的地方。
故事板/XIB设置
首先要做的是在IB(或代码)中配置不会更改的约束。即红色视图的高度以及其与容器的前导和尾随间距。因此,您的约束可能如下所示(请注意:我没有设置宽度约束,而是让前导和尾随空间定义宽度):
现在,您将看到IB会警告您没有为视图的Y位置配置约束(因此是红色虚线)。
您现在可以添加顶部空间到容器约束,并将其设置为占位符约束(勾选框说“在构建时删除”)。我们这样做是因为我们想通过编程方式控制视图的位置。
这意味着,一旦加载视图,这个约束就不存在了,但是它可以消除所有警告,因为您告诉IB,当视图加载时,您知道如何处理这个约束。
编码时间
现在我们需要一个隐藏视图的方法,一个显示视图的方法。为此,我们将存储视图上的Y定位约束,然后对其进行动画处理。我们的viewController可能如下所示:
@IBOutlet weak var redView: UIView!
var redViewYPositionConstraint: NSLayoutConstraint?
override func viewDidLoad() {
super.viewDidLoad()
self.hideRedViewAnimated(false)
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
self.showRedViewAnimated(true)
}
隐藏
我们隐藏视图的方法很简单,只需删除位置约束,然后添加一个将红色视图底部与视图控制器顶部相等的约束:
func hideRedViewAnimated(animated: Bool) {
self.removeRedViewYPositionConstraint()
let hideConstraint = NSLayoutConstraint(item: self.redView,
attribute: .Bottom,
relatedBy: .Equal,
toItem: self.view,
attribute: .Top,
multiplier: 1,
constant: 0)
self.redViewYPositionConstraint = hideConstraint
self.view.addConstraint(hideConstraint)
self.performConstraintLayout(animated: animated)
}
展示
类似地,我们的展示约束将把视图中心Y移动到控制器的中心Y:
func showRedViewAnimated(animated: Bool) {
self.removeRedViewYPositionConstraint()
let centerYConstraint = NSLayoutConstraint(item: self.redView,
attribute: .CenterY,
relatedBy: .Equal,
toItem: self.view,
attribute: .CenterY,
multiplier: 1,
constant: 0)
self.redViewYPositionConstraint = centerYConstraint
self.view.addConstraint(centerYConstraint)
self.performConstraintLayout(animated: animated)
}
便捷方法
为了完整起见,我使用的便捷方法如下:
func performConstraintLayout(animated animated: Bool) {
if animated == true {
UIView.animateWithDuration(1,
delay: 0,
usingSpringWithDamping: 0.5,
initialSpringVelocity: 0.6,
options: .BeginFromCurrentState,
animations: { () -> Void in
self.view.layoutIfNeeded()
}, completion: nil)
} else {
self.view.layoutIfNeeded()
}
}
func removeRedViewYPositionConstraint() {
if redViewYPositionConstraint != nil {
self.view.removeConstraint(self.redViewYPositionConstraint!)
self.redViewYPositionConstraint = nil
}
}
您还可以通过进行一些CGRect数学计算来检查红色视图是否可见:
func isRedViewVisible() -> Bool {
return CGRectContainsPoint(self.view.bounds, self.redView.frame.origin)
}