iOS点点滴滴iOS Developer

Masnory动画小记

2017-09-24  本文已影响86人  mkvege

Masnory 不需要weakSelf

masnory中的block使用原理和UIView 动画中的block 以及 AFN 中的block 原理一样,block作为函数参数不会被copy,则认为self 没有强引用 block,block中引用self 也就不会造成循环引用。

Masnory 动画

在UIview 动画回调中直接更改Masnory约束是没有动画效果的

[UIView animateWithDuration:0.25 animations:^{
        [redView mas_updateConstraints:^(MASConstraintMaker *make) {
            make.width.mas_equalTo(width);
        }];
 }];

挂档的正确姿势

[redView mas_updateConstraints:^(MASConstraintMaker *make) {
        make.width.mas_equalTo(width);
 }];
 [UIView animateWithDuration:5 animations:^{
        [self layoutIfNeeded];
 }];

或者这样

[UIView animateWithDuration:5 animations:^{
        [redView mas_updateConstraints:^(MASConstraintMaker *make) {
            make.width.mas_equalTo(width);
        }];
        [self layoutIfNeeded];
 }];

可以看出挂档的关键点是 layoutIfNeed,苹果的官方文档这么形容

Lays out the subviews immediately, if layout updates are pending.
Use this method to force the view to update its layout immediately. When using Auto Layout, the layout engine updates the position of views as needed to satisfy changes in constraints. Using the view that receives the message as the root view, this method lays out the view subtree starting at the root. If no layout updates are pending, this method exits without modifying the layout or calling any layout-related callbacks.

大致就是说会立即约束子视图,也就是立即调用layoutSubviews 方法去从根视图(这个根视图就是调用layoutIfNeed 的视图,所以要调用self 的 layotIfNeed,而不是redView的layoutIfNeed)开始执行layoutSubviews,执行完根视图再去执行子视图的layoutSubviews,如果没有约束被标记更新,则不去调用任何视图的layoutSubviews方法。苹果在layoutSubview的文档中说不让直接调用,只能通过layoutIfNeed来主动调用。

与layoutIfNeed形成鲜明对比的是setNeedsLayout

Invalidates the current layout of the receiver and triggers a layout update during the next update cycle.

大致含义:标记更新,但是不立即更新,在下一个更新循环中更新。

在Masnory修改约束过程中会自动调用setNeedsLayout 方法,来自动标记更新,等待RunLoop 自动刷新屏幕的时候才真正改变子视图的frame,而调用layoutIfNeed则直接改变子视图的frame,二者在显示上的差别可能只有零点零几秒,我们肉眼看不出差别,但是计算机动画的执行顺序就会不一样,先改变再动画就会有动画效果,先动画再改变就没有动画效果。这也就解释了为什么下面这种情况不能显示动画

[UIView animateWithDuration:0.25 animations:^{
        [redView mas_updateConstraints:^(MASConstraintMaker *make) {
            make.width.mas_equalTo(width);
        }];
 }];

因为在动画执行的时候只执行了setNeedslayout,并没有发生真正的改变,所以系统显示不变化,而在下一次系统刷新屏幕后,发现了被标记的约束改变就会执行layoutSubviews,但是此刻已经没有动画了。

Masnory实践篇 实现仿facebook 的点赞动画

实践篇用masnory 实现仿照 facebook 的点赞动画。我写了一个小demo实现上图的效果。这里是Demo

上一篇下一篇

猜你喜欢

热点阅读