这个问题纠结了我挺长时间的。一直以为把约束直接添加到动画里面就可以了。但是并没那么简单。-.-其实还是挺简
class ViewController: UIViewController { @IBOutlet weak var usernameOutlet: UITextField!
@IBOutlet weak var animateBtn: UIButton!
let boxView = UIView()
var topConstraint: Constraint? = nil @IBAction func animateBtnClick(sender: UIButton) {
UIView.animateWithDuration() { self.boxView.snp_updateConstraints(closure: { (make) -> Void in
make.top.equalTo(self.view).offset()
})
self.view.layoutIfNeeded()
// self.view.setNeedsDisplay()
// self.view.setNeedsLayout()
// self.view.layoutSubviews() }
} override func viewDidLoad() {
super.viewDidLoad()
let tapGesture = UITapGestureRecognizer(target: self, action: "tapBg:")
view.addGestureRecognizer(tapGesture)
boxView.backgroundColor = UIColor.purpleColor()
self.view.addSubview(boxView) boxView.snp_makeConstraints { (make) -> Void in
self.topConstraint = make.top.equalTo(self.view).offset().constraint
make.left.equalTo(self.view).offset()
make.size.equalTo(CGSize(width: , height: ))
}
} }
对于这个layoutIfNeeded, 还有一个地方我们经常会碰到,就是设置约束我们如何才能立马得到frame的数值:
view.superview. layoutIfneed()
今天要谈的重点来了, iOS layout 相关机制
- (CGSize)sizeThatFits:(CGSize)size
- (void)sizeToFit - (void)layoutSubviews
- (void)lauoutIfNeeded
- (void)setNeedsLayout - (void)setNeedsDisplay
- (void)drawRect
1. layoutSubviews:
- init 不会触发
- addsubview 会触发
- 设置view的frame(有变化的)
- 滚动一个UIScroollView会
- 旋转Screen,触发父UIView上的layoutSubViews事件
- 直接调用setLayoutSubviews
- 直接调用setNeedsLayout
You should override this method only if the autoresizing behaviors of the subviews do not offer the behavior you want. // layoutSubviews, 当我们在某个类的内部调整子视图位置时,需要调用。
刷新子对象布局:
- layoutSubviews: 不做任何事情,需要重写
- setNeedsLayout: 标记为需要重新布局,异步调用layoutIfNeeded刷新布局,不立即刷新,但是layoutSubviews一定会被调用
- layoutIfNeeded: 如果有需要刷新新的标记,立即调用layoutSubviews进行布局
如果需要立即刷新,需要先view.setNeedsLayout()(设置标记),然后调用view.layoutIfneeded()立即刷新