通过将 UIView 过渡添加到 UIStackView 来制作动画
Posted
技术标签:
【中文标题】通过将 UIView 过渡添加到 UIStackView 来制作动画【英文标题】:Animate UIView transition by adding it to a UIStackView 【发布时间】:2019-06-28 15:17:30 【问题描述】:我有一个自定义对象,它是UIView
的子类。我想要的行为是让这个对象最初出现在屏幕中间。然后,在 3 秒后,我希望对象转换(带有平滑动画)到已经有一个元素的水平 UIStackView
,所以 customObject
理想情况下会移动到 stackView
的右半部分。
我目前无法实现此行为。
ViewController.swift:
class ViewController: UIViewController
let customObject = CustomObject(frame: .init(x: 0,
y: 0,
width: 200.0,
height: 200.0))
let stackView: UIStackView =
let sv = UIStackView()
sv.axis = .horizontal
return sv
()
override func viewDidLoad()
super.viewDidLoad()
let label = UILabel()
label.text = "first Element in horizontal stackView"
stackView.addArrangedSubview(label)
addCustomObjectToStackView()
func addCustomObjectToStackView()
stackView.addArrangedSubview(customObject)
UIView.animate(withDuration: 1.0, animations:
customObject.layoutIfNeeded()
)
【问题讨论】:
张贴一张你希望它在开始时的样子,以及你希望它在动画后的样子。它真的需要在堆栈视图中结束吗? 是的,我绝对希望它最终出现在 stackView 中。我知道如何为UIView
设置动画,否则。另外,我会发布一张图片
给你@DonMag
【参考方案1】:
由于UIStackView
旨在安排其子视图,因此以这种方式进行动画添加可能很难完成。
所以,一个选择:
在 stackView 中以明确的“holderView
”开头
将您的 customObject
添加到主视图(它现在是 stackView 的兄弟)
动画customObject
的位置和大小以匹配holderView
在动画完成时,添加customObject
作为holderView
的子视图
这里有一些示例代码可供试用(注意:只是演示代码,尚未准备好用于生产):
//
// AnimToStackViewController.swift
//
// Created by Don Mag on 6/28/19.
//
import UIKit
class CustomObject: UIView
override init(frame: CGRect)
super.init(frame: frame)
let theLabel = UILabel()
theLabel.textAlignment = .center
theLabel.text = "Custom Object"
theLabel.translatesAutoresizingMaskIntoConstraints = false
addSubview(theLabel)
NSLayoutConstraint.activate([
theLabel.centerXAnchor.constraint(equalTo: centerXAnchor),
theLabel.centerYAnchor.constraint(equalTo: centerYAnchor),
])
backgroundColor = .cyan
required init?(coder aDecoder: NSCoder)
fatalError("init(coder:) has not been implemented")
class AnimToStackViewController: UIViewController
let theStackView: UIStackView =
let v = UIStackView()
v.translatesAutoresizingMaskIntoConstraints = false
v.axis = .horizontal
v.alignment = .fill
v.distribution = .fill
return v
()
let theLabel: UILabel =
let v = UILabel()
v.textAlignment = .center
v.text = "This is the label in the stack view."
v.numberOfLines = 0
return v
()
let holderView: UIView =
let v = UIView()
v.translatesAutoresizingMaskIntoConstraints = false
return v
()
let customObject = CustomObject(frame: CGRect(x: 0, y: 0, width: 150, height: 150))
override func viewDidLoad()
super.viewDidLoad()
view.addSubview(theStackView)
theStackView.addArrangedSubview(theLabel)
theStackView.addArrangedSubview(holderView)
view.addSubview(customObject)
NSLayoutConstraint.activate([
theStackView.widthAnchor.constraint(equalToConstant: 300.0),
theStackView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 80.0),
theStackView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
holderView.widthAnchor.constraint(equalTo: customObject.widthAnchor, constant: 0.0),
holderView.heightAnchor.constraint(equalTo: customObject.heightAnchor, constant: 0.0),
])
customObject.center = view.center
override func viewDidAppear(_ animated: Bool)
super.viewDidAppear(animated)
let pt = self.holderView.center
let convertedPoint = self.theStackView.convert(pt, to: self.view)
UIView.animate(withDuration: 1.0, delay: 3.0, options: [], animations:
self.customObject.center = convertedPoint
self.view.layoutIfNeeded()
, completion: (finished) in
if finished
self.holderView.addSubview(self.customObject)
self.customObject.frame = self.holderView.bounds
)
【讨论】:
感谢您的详细解答!我正在尝试。会尽快通知您以上是关于通过将 UIView 过渡添加到 UIStackView 来制作动画的主要内容,如果未能解决你的问题,请参考以下文章