nai*_*per 43 uiviewanimation ios swift xcode6
在我的设计示例中,我有以下单一视图:

如您所见,它包含一些简单的约束:
我想要实现的是让这个红色/粉红色的视图从顶部"进入".传统上,在一个无约束的世界中,我只是修改内部的框架UIView.animateWithDuration,但是我不确定我是如何在约束世界中做类似的.
为了重申我的问题,如何让我的视图从场景开始并使从顶部飞入的视图动画?
我已经考虑过制作垂直中心约束(并随后调用layoutIfNeeded),但它没有达到预期的效果.
谢谢你的帮助.
gab*_*ler 69
您可以做的是在viewDidAppear方法中添加以下代码.首先创建IBOutlet视图中心Y约束的属性,然后更改其常量值.
self.centerYConstraint.constant = 500.0
self.view.layoutIfNeeded()
UIView.animateWithDuration(Double(0.5), animations: {
self.centerYConstraint.constant = 0
self.view.layoutIfNeeded()
})
Run Code Online (Sandbox Code Playgroud)
Dan*_*sko 14
你想要的实际上相当简单,我将详细说明如何在不搞乱优先级或时髦常数的情况下完成它.通过这种方式,我们可以获得适用于任何屏幕尺寸的动画.
TL; DR是您需要配置约束,然后在动画块内调用layoutIfNeeded来为更改设置动画.欲了解更多,请参阅此SO帖子.
因此,我们需要两组约束来隐藏和显示视图.在viewDidLoad视图中将被隐藏,然后在viewDidAppear我们希望该视图滑入的任何地方.
所以首先要配置不会在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)
}
Run Code Online (Sandbox Code Playgroud)
我们隐藏视图的方法可以简单地删除位置约束,然后添加一个红色视图底部等于视图控制器的视图顶部:
func hideRedViewAnimated(animated: Bool) {
//remove current constraint
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)
//animate changes
self.performConstraintLayout(animated: animated)
}
Run Code Online (Sandbox Code Playgroud)
同样,我们的show约束会将视图的中心Y移动到控制器中心Y:
func showRedViewAnimated(animated: Bool) {
//remove current constraint
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)
//animate changes
self.performConstraintLayout(animated: animated)
}
Run Code Online (Sandbox Code Playgroud)
为了完整起见,我使用的便捷方法如下所示:
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
}
}
Run Code Online (Sandbox Code Playgroud)
您还可以使用一些CGRect数学检查红色视图是否可见:
func isRedViewVisible() -> Bool {
return CGRectContainsPoint(self.view.bounds, self.redView.frame.origin)
}
Run Code Online (Sandbox Code Playgroud)
rin*_*aro 10
试试这个:
class ViewController: UIViewController {
// red view
@IBOutlet weak var myView: UIView!
// vertical align contraint
@IBOutlet weak var verticalConstraint: NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
verticalConstraint.constant = (myView.bounds.height + self.view.bounds.height)/2
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
self.view.layoutIfNeeded()
UIView.animateWithDuration(0.5) {
self.verticalConstraint.constant = 0
self.view.layoutIfNeeded()
}
}
}
Run Code Online (Sandbox Code Playgroud)
在约束中要小心firstItem并secondItem排序.上面的代码假设Superview是firstItem:

另一种方法是定义两个约束:

并调整优先级以确定应采用哪种约束.
class ViewController: UIViewController {
// vertical align contraint
@IBOutlet weak var centerYConstraint: NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
centerYConstraint.priority = 250
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
self.view.layoutIfNeeded()
UIView.animateWithDuration(0.5) {
self.centerYConstraint.priority = 750
self.view.layoutIfNeeded()
}
}
}
Run Code Online (Sandbox Code Playgroud)
对于任何寻找像请求这样的简单动画的人:
对于上滑动画,您需要使用 CGAffineTransformMakeTranslation(x,y).
原因是对于向上滑动动画,您需要先将视图移出屏幕,然后将其恢复到原始位置.所以在你的viewDidLoad中只需使用:
Run Code Online (Sandbox Code Playgroud)yourView.transform = CGAffineTransformMakeTranslation(0, 500)这会将视图移出屏幕,在本例中位于底部.现在在 viewDidAppear中,您可以显示您的视图:
Run Code Online (Sandbox Code Playgroud)UIView.animateWithDuration(0.7, delay: 0.0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.5, options: [], animations: { self.yourView.transform = CGAffineTransformMakeScale(1, 1) }, completion: nil)
使用这些行,您可以在UIView上添加所需的约束,并将其放在ViewController中所需的位置.
对我来说,制作Swift 3 和 4动画的最佳方式
self.constraint.constant = -150
UIView.animate(withDuration: 0.45) { [weak self] in
self?.view.layoutIfNeeded()
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
41660 次 |
| 最近记录: |