Gol*_*Joe 5 animation uiview ios autolayout swift
我可以在网上找到所有UIViewPropertyAnimator使用视图的示例,这些视图是通过设置框架而不是使用自动布局来布局的,这就是视图通常的布局方式.使用自动布局时,视图会动画到我想要的位置,但之后我不确定如何将其设置回"模型"位置.
// Move a view that is constrained to the center of its superview
UIViewPropertyAnimator(duration: 1, curve: .linear) {
testView.center = CGPoint(x: 10, y: 10)
}.startAnimation()
Run Code Online (Sandbox Code Playgroud)
它显然增加了某种约束?我在执行动画之前和之后记录了容器视图的约束:
CONSTRAINTS BEFORE:
view: [<NSLayoutConstraint:0x618000094f00 UIView:0x7fd764004050.centerX == UIView:0x7fd75fd00000.centerX (active)>, <NSLayoutConstraint:0x618000092de0 UIView:0x7fd764004050.centerY == UIView:0x7fd75fd00000.centerY (active)>]
CONSTRAINTS AFTER:
view: [<NSLayoutConstraint:0x618000094f00 UIView:0x7fd764004050.centerX == UIView:0x7fd75fd00000.centerX (active)>, <NSLayoutConstraint:0x618000092de0 UIView:0x7fd764004050.centerY == UIView:0x7fd75fd00000.centerY (active)>, <NSLayoutConstraint:0x6100000922a0 'UIView-Encapsulated-Layout-Height' UIView:0x7fd75fd00000.height == 667 (active)>, <NSAutoresizingMaskLayoutConstraint:0x610000092570 h=-&- v=-&- 'UIView-Encapsulated-Layout-Left' UIView:0x7fd75fd00000.minX == 0 (active, names: '|':UIWindow:0x7fd75fc07110 )>, <NSAutoresizingMaskLayoutConstraint:0x610000092890 h=-&- v=-&- 'UIView-Encapsulated-Layout-Top' UIView:0x7fd75fd00000.minY == 0 (active, names: '|':UIWindow:0x7fd75fc07110 )>, <NSLayoutConstraint:0x610000091670 'UIView-Encapsulated-Layout-Width' UIView:0x7fd75fd00000.width == 375 (active)>]
Run Code Online (Sandbox Code Playgroud)
这里发生了什么?我该如何处理使用自动布局定位的视图的动画?Apple是否鼓励用户回归基于框架的布局?
vac*_*ama 18
您可以使用UIViewPropertyAnimator带有自动布局,但需要修改,而不是视图的框架的限制,并呼吁layoutIfNeeded()封闭的内部.
第一个例子:通过修改约束来动画 constant
在Storyboard中创建一个视图.创建约束以centerX将视图定位为等于超视图的前沿.创建一个@IBOutlet到该约束并调用它centerXConstraint.同样,创建一个将视图centerYConstraint定位为centerY等于其超级视图顶部的视图.这两个约束都应该有constant = 0.
创建@IBOutlet约束条件:
@IBOutlet weak var centerXConstraint: NSLayoutConstraint!
@IBOutlet weak var centerYConstraint: NSLayoutConstraint!
Run Code Online (Sandbox Code Playgroud)
将constant约束的值设置为新位置,然后view.layoutIfNeeded()在以下内部调用UIViewPropertyAnimator:
// Make sure view has been laid out
view.layoutIfNeeded()
// Set new X and Y locations for the view
centerXConstraint.constant = 50
centerYConstraint.constant = 80
UIViewPropertyAnimator(duration: 1, curve: .easeInOut) {
self.view.layoutIfNeeded()
}.startAnimation()
Run Code Online (Sandbox Code Playgroud)
第二个示例:通过激活新约束进行动画处理
在Storyboard中创建一个视图(例如redView)并@IBOutlet在代码中创建一个视图:
@IBOutlet weak var redView: UIView!
Run Code Online (Sandbox Code Playgroud)
创建@IBOutlet用于控制视图位置的约束
// Outlets to the constraints set in the Storyboard
@IBOutlet weak var topConstraint: NSLayoutConstraint!
@IBOutlet weak var leadingConstraint: NSLayoutConstraint!
Run Code Online (Sandbox Code Playgroud)
然后是时候动画了:
// Make sure view has been laid out
view.layoutIfNeeded()
// Deactivate the old constraints
topConstraint.isActive = false
leadingConstraint.isActive = false
// Active new constraints that move view to the bottom right
redView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
redView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
// Animate the change
UIViewPropertyAnimator(duration: 1, curve: .easeInOut) {
self.view.layoutIfNeeded()
}.startAnimation()
Run Code Online (Sandbox Code Playgroud)
那么这比旧
UIView动画块更好?
UIViewPropertyAnimator是一个可以配置为以各种方式控制动画的对象.这是一个完整的示例,演示:
class ViewController: UIViewController {
@IBOutlet weak var redView: UIView!
@IBOutlet weak var centerXConstraint: NSLayoutConstraint!
@IBOutlet weak var centerYConstraint: NSLayoutConstraint!
@IBOutlet weak var slider: UISlider!
override func viewDidLoad() {
super.viewDidLoad()
slider.isHidden = true
}
var myAnimator: UIViewPropertyAnimator?
@IBAction func startAnimation(_ sender: UIButton) {
view.layoutIfNeeded()
centerXConstraint.isActive = false
centerYConstraint.isActive = false
redView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
redView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
myAnimator = UIViewPropertyAnimator(duration: 10, curve: .easeInOut) {
self.view.layoutIfNeeded()
}
myAnimator?.startAnimation()
}
@IBAction func pauseAnimation(_ sender: UIButton) {
guard let myAnimator = myAnimator else { return }
myAnimator.pauseAnimation()
print("The animation is \(String(format: "%.1f", myAnimator.fractionComplete * 100))% complete")
slider.value = Float(myAnimator.fractionComplete)
slider.isHidden = false
}
@IBAction func scrub(_ sender: UISlider) {
myAnimator?.fractionComplete = CGFloat(sender.value)
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3078 次 |
| 最近记录: |