为了简单起见,假设您希望 viewOne 从零变为 100,并且 viewTwo 高度从零变为 200...
如果将 viewOne 的动画持续时间设置为 1 秒,则 viewTwo 的持续时间需要为 2 秒。
所以,你可以这样做:
// duration for viewOne animation
let dur1 = 0.5
// calculate needed duration for viewTwo animation
let dur2 = (1000.0 / 150.0) * dur1
UIView.animate(withDuration: dur1, delay: 0.0, options: [.curveLinear], animations: {
self.con_ViewOneHeight.constant = 150.0
self.view.layoutIfNeeded()
}, completion: nil)
UIView.animate(withDuration: dur2, delay: 0.0, options: [.curveLinear], animations: {
self.con_ViewTwoHeight.constant = 1000.0
self.view.layoutIfNeeded()
}, completion: nil)
这是一个工作示例。点击视图中的任意位置以展开 viewOne(蓝色)和 viewTwo(红色)。每次点击都会重置并重新运行动画:
class DoubleGrowViewController: UIViewController {
let viewOne = UIView()
let viewTwo = UIView()
var con_ViewOneHeight: NSLayoutConstraint!
var con_ViewTwoHeight: NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
viewOne.translatesAutoresizingMaskIntoConstraints = false
viewTwo.translatesAutoresizingMaskIntoConstraints = false
viewOne.backgroundColor = .blue
viewTwo.backgroundColor = .red
view.addSubview(viewOne)
view.addSubview(viewTwo)
con_ViewOneHeight = viewOne.heightAnchor.constraint(equalToConstant: 0.0)
con_ViewTwoHeight = viewTwo.heightAnchor.constraint(equalToConstant: 0.0)
// respect safe-area
let g = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
viewOne.topAnchor.constraint(equalTo: g.topAnchor, constant: 20.0),
viewOne.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 20.0),
viewOne.widthAnchor.constraint(equalToConstant: 150.0),
con_ViewOneHeight,
viewTwo.topAnchor.constraint(equalTo: g.topAnchor, constant: 20.0),
viewTwo.leadingAnchor.constraint(equalTo: viewOne.trailingAnchor, constant: 20.0),
viewTwo.widthAnchor.constraint(equalToConstant: 150.0),
con_ViewTwoHeight,
])
let t = UITapGestureRecognizer(target: self, action: #selector(self.doAnim(_:)))
view.addGestureRecognizer(t)
}
@objc func doAnim(_ g: UITapGestureRecognizer?) -> Void {
// if the animation is running, we'll
// stop it
// reset view height constraints to 0
// re-start the animation (async)
if con_ViewOneHeight.constant != 0.0 {
viewOne.layer.removeAllAnimations()
viewTwo.layer.removeAllAnimations()
con_ViewOneHeight.constant = 0.0
con_ViewTwoHeight.constant = 0.0
DispatchQueue.main.async {
self.doAnim(nil)
}
return
}
// duration for viewOne animation
let dur1 = 0.5
// calculate needed duration for viewTwo animation
let dur2 = (1000.0 / 150.0) * dur1
UIView.animate(withDuration: dur1, delay: 0.0, options: [.curveLinear], animations: {
self.con_ViewOneHeight.constant = 150.0
self.view.layoutIfNeeded()
}, completion: nil)
UIView.animate(withDuration: dur2, delay: 0.0, options: [.curveLinear], animations: {
self.con_ViewTwoHeight.constant = 1000.0
self.view.layoutIfNeeded()
}, completion: nil)
}
}