Ios 使用动画自动布局视图
我有一个自定义视图、自定义布局蓝色、自定义UIView,该视图包含3个子视图,通过使用约束布局锚垂直对齐,每个视图按照以下顺序对齐: 1视图:幻灯片显示红色,自定义UIView 2视图:UIButton黄色 3视图:UIView干灰色 我想当我点击黄色按钮时,SlideLayout红色的高度大小在打开时会增加,在关闭时会减少,使用动画。其他视图必须在动画期间更改位置,并且如果SlideLayout增加/减少,则父视图CustomLayout必须增加/减少其高度大小动画 使用此方法时调用什么方法: UIView.animatewithDuration、delay、选项、动画、完成 我通过添加一个简单的打印来覆盖layoutIfNeeded方法,但它不会在动画期间每次调用 我试过了,但没有达到预期效果。我怎样才能解决这个问题谢谢你 代码:Ios 使用动画自动布局视图,ios,swift,animation,autolayout,Ios,Swift,Animation,Autolayout,我有一个自定义视图、自定义布局蓝色、自定义UIView,该视图包含3个子视图,通过使用约束布局锚垂直对齐,每个视图按照以下顺序对齐: 1视图:幻灯片显示红色,自定义UIView 2视图:UIButton黄色 3视图:UIView干灰色 我想当我点击黄色按钮时,SlideLayout红色的高度大小在打开时会增加,在关闭时会减少,使用动画。其他视图必须在动画期间更改位置,并且如果SlideLayout增加/减少,则父视图CustomLayout必须增加/减少其高度大小动画 使用此方法时调用什么方法:
class CustomLayout: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
private func setup() {
onLayout()
}
public func onLayout() {
print("\(frame.size.height)")
let MARGIN: CGFloat = 10
for i in 0 ..< subviews.count {
let child = subviews[i]
if i == 0 { // slide layout
child.translatesAutoresizingMaskIntoConstraints = false
child.topAnchor.constraint(equalTo: topAnchor, constant: MARGIN).isActive = true
child.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
child.widthAnchor.constraint(equalToConstant: frame.size.width - (MARGIN * 2)).isActive = true
let enchorHeight = child.heightAnchor.constraint(equalToConstant: child.frame.size.height);
enchorHeight.isActive = true
(subviews[0] as! SlideDownLayout).enchorHeight = enchorHeight
}
else if i == 1 { // button
child.translatesAutoresizingMaskIntoConstraints = false
child.topAnchor.constraint(equalTo: subviews[0].bottomAnchor, constant: MARGIN).isActive = true
child.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
child.widthAnchor.constraint(equalToConstant: child.frame.size.width).isActive = true
child.heightAnchor.constraint(equalToConstant: child.frame.size.height).isActive = true
}
else if i == 2 { // uiview
child.translatesAutoresizingMaskIntoConstraints = false
child.topAnchor.constraint(equalTo: subviews[1].bottomAnchor, constant: MARGIN).isActive = true
child.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
child.widthAnchor.constraint(equalToConstant: frame.size.width - (MARGIN * 4)).isActive = true
child.heightAnchor.constraint(equalToConstant: 300).isActive = true
bottomAnchor.constraint(equalTo: child.bottomAnchor, constant: MARGIN).isActive = true
}
}
}
}
class SlideDownLayout: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
private var HEIGHT: CGFloat = 0
private var isClosed: Bool = true
private func setup() {
HEIGHT = frame.height
frame.size.height = 0
}
public func slideAnimation(view: UIView) {
print("\(HEIGHT)")
isClosed = !isClosed
self.enchorHeight!.constant = self.isClosed ? 0 : self.HEIGHT
UIView.animate(withDuration: 1, delay: 0, options: .curveEaseInOut, animations: {
self.superview?.layoutIfNeeded()
view.layoutIfNeeded()
}, completion: nil)
}
override func layoutIfNeeded() {
print("...")
super.layoutIfNeeded()
}
var enchorHeight: NSLayoutConstraint? = nil
}
class ViewController: UIViewController {
@IBOutlet weak var customLayout: CustomLayout!
@IBOutlet weak var slideDownLayout: SlideDownLayout!
override func viewDidLoad() {
super.viewDidLoad()
customLayout.translatesAutoresizingMaskIntoConstraints = false
customLayout.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
customLayout.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 0).isActive = true
customLayout.rightAnchor.constraint(equalTo: view.rightAnchor, constant: 0).isActive = true
customLayout.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
}
override var prefersStatusBarHidden: Bool {
return true
}
@IBAction
func buttonListener(_ sender: Any) {
slideDownLayout.slideAnimation(view: self.view)
}
}
当您要创建动态视图时,不要更改帧,而是更改约束的常量,因为帧不会向下推父视图,所以请创建要设置动画的视图的高度约束,并控制其常量值 你可以试试
class CustomLayout: UIView {
var heightCon:NSLayoutConstraint!
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
private func setup() {
onLayout()
}
public func onLayout() {
print("\(frame.size.height)")
let MARGIN: CGFloat = 10
for i in 0 ..< subviews.count {
let child = subviews[i]
if i == 0 { // slide layout
child.translatesAutoresizingMaskIntoConstraints = false
child.topAnchor.constraint(equalTo: topAnchor, constant: MARGIN).isActive = true
child.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
child.widthAnchor.constraint(equalToConstant: frame.size.width - (MARGIN * 2)).isActive = true
heightCon = child.heightAnchor.constraint(equalToConstant: child.frame.size.height)
heightCon.isActive = true
}
尝试使用stackViewthank you,我看不到你的代码更新我按照你说的做了,动画工作,但父级大小没有增加或减少,我更新了我的代码钩住最底部视图的底部约束以更新我的代码,我有底部约束,但打开时视图不从顶部开始,且底部边距超过I=2处视图的父视图集高度谢谢您的帮助我将此行替换为child.bottomAnchor.constraintequalTo:bottomAnchor,constant:margin.isActive=true by bottomAnchor.constraintequalTo:child.bottomAnchor,常量:MARGIN.isActive=true child i=2 CustmLayout,现在工作正常
public func slideAnimation() {
print("\(HEIGHT)")
isClosed = !isClosed
let ss = self.superview as! CustomLayout
ss.heightCon.constant = self.isClosed ? 0 : self.HEIGHT
UIView.animate(withDuration: 1, delay: 0, options: .curveEaseInOut, animations: {
ss.layoutIfNeeded()
}, completion: nil)
}