Masonry框架詳細(xì)解析(七) —— Masonry與動畫(一)

版本記錄

版本號 時間
V1.0 2019.01.05 星期六

前言

我們做APP界面,也就是布局UI,那么關(guān)于布局,我們有很多方法,蘋果也都提供了支持,市場上我們用的并不是系統(tǒng)提供原生的layout,對于OC語言一般都是使用一個第三方的布局框架 —— Masonry。接下來幾篇我們就一起深入看一下這個框架。感興趣的看上面幾篇文章。
1. Masonry框架詳細(xì)解析(一) —— 基本概覽(一)
2. Masonry框架詳細(xì)解析(二) —— 基本結(jié)構(gòu)API和約束入口(一)
3. Masonry框架詳細(xì)解析(三) —— MASConstraintMaker工廠類(一)
4. Masonry框架詳細(xì)解析(四) —— MASConstraint類解析(一)
5. Masonry框架詳細(xì)解析(五) —— MASCompositeConstraint類解析(一)
6. Masonry框架詳細(xì)解析(六) —— MASViewConstraint類解析(一)

常見的UIView的類動畫

UIView有一個分類,專門針對視圖的動畫的,主要API如下所示,也是大家都用過的。

@interface UIView(UIViewAnimationWithBlocks)

+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^ __nullable)(BOOL finished))completion NS_AVAILABLE_IOS(4_0);

+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations completion:(void (^ __nullable)(BOOL finished))completion NS_AVAILABLE_IOS(4_0); // delay = 0.0, options = 0

+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations NS_AVAILABLE_IOS(4_0); // delay = 0.0, options = 0, completion = NULL

/* Performs `animations` using a timing curve described by the motion of a spring. When `dampingRatio` is 1, the animation will smoothly decelerate to its final model values without oscillating. Damping ratios less than 1 will oscillate more and more before coming to a complete stop. You can use the initial spring velocity to specify how fast the object at the end of the simulated spring was moving before it was attached. It's a unit coordinate system, where 1 is defined as travelling the total animation distance in a second. So if you're changing an object's position by 200pt in this animation, and you want the animation to behave as if the object was moving at 100pt/s before the animation started, you'd pass 0.5. You'll typically want to pass 0 for the velocity. */ 
+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay usingSpringWithDamping:(CGFloat)dampingRatio initialSpringVelocity:(CGFloat)velocity options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^ __nullable)(BOOL finished))completion NS_AVAILABLE_IOS(7_0);

+ (void)transitionWithView:(UIView *)view duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void (^ __nullable)(void))animations completion:(void (^ __nullable)(BOOL finished))completion NS_AVAILABLE_IOS(4_0);

+ (void)transitionFromView:(UIView *)fromView toView:(UIView *)toView duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options completion:(void (^ __nullable)(BOOL finished))completion NS_AVAILABLE_IOS(4_0); // toView added to fromView.superview, fromView removed from its superview

/* Performs the requested system-provided animation on one or more views. Specify addtional animations in the parallelAnimations block. These additional animations will run alongside the system animation with the same timing and duration that the system animation defines/inherits. Additional animations should not modify properties of the view on which the system animation is being performed. Not all system animations honor all available options.
 */
+ (void)performSystemAnimation:(UISystemAnimation)animation onViews:(NSArray<__kindof UIView *> *)views options:(UIViewAnimationOptions)options animations:(void (^ __nullable)(void))parallelAnimations completion:(void (^ __nullable)(BOOL finished))completion NS_AVAILABLE_IOS(7_0);

@end

這個相信大家都用過,這里就弄個簡單的例子吧,直接上代碼。

#import "AVC.h"
#import "Masonry.h"

@interface AVC ()

@property (nonatomic, strong) UIView *animatedView;

@end

@implementation AVC

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    self.title = NSStringFromClass([self class]);
    
    UIView *animatedView = [[UIView alloc] initWithFrame:CGRectMake(50.0, 150.0, 100.0, 100.0)];
    animatedView.backgroundColor = [UIColor redColor];
    [self.view addSubview:animatedView];
    self.animatedView = animatedView;
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    NSLog(@"animatedView = %@", self.animatedView);
    
    [UIView transitionWithView:self.animatedView duration:2.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
        self.animatedView.frame = CGRectMake(self.animatedView.frame.origin.x, 600.0, self.animatedView.frame.size.width, self.animatedView.frame.size.height);
    } completion:^(BOOL finished) {
        
    }];
}

@end

這里首先看下輸出

2019-01-05 17:24:40.100905+0800 JJTest[41091:334070] animatedView = <UIView: 0x7fb690519830; frame = (50 150; 100 100); layer = <CALayer: 0x60000237d3c0>>

可以看見這個view是布局好我們可以看到其frame不是CGRectZero,下面我們就看下效果


Masonry約束與動畫

上面的我們看見UIView實例化的時候是給了frame的,那么如果我們布局使用Masonry布局呢?還是一樣的嗎?我們平時項目中最常用的就是使用Masonry進(jìn)行相對布局,不會這么寫死數(shù)據(jù)。

因為有的時候正在加載視圖,所以view只是相對布局還沒有生效,沒有frame,打印出來就會發(fā)現(xiàn)全部是0。

//如果約束還沒有生成,要強制約束生成才行,不然動畫沒用
[self.view layoutIfNeeded];
    
[self.animatedView mas_updateConstraints:^(MASConstraintMaker *make) {
        make.bottom.equalTo(self.view.mas_bottom).offset(-(44 + 44));}];
    
[UIView animateWithDuration:0.25
                      delay:0.0
                    options:UIViewAnimationOptionCurveEaseInOut
                 animations:^{
                        //告知父視圖生效約束
                       [self.view layoutIfNeeded];
                  } completion:^(BOOL finished) {
                         
                 }];

所以,這里需要注意的是,在我們添加完視圖并且設(shè)置了約束后若是想要立即獲得該視圖的frame 或者 想要進(jìn)行該視圖的動畫的話,就必須要在設(shè)置完約束后立即調(diào)用layoutIfNeeded方法強制進(jìn)行刷新。

查閱了下資料,還有像IOS開發(fā)-利用Masonry實現(xiàn)簡單動畫寫的。

和普通的方法實現(xiàn)差不多,重點只是修改約束后調(diào)用而已

[view.superview layoutIfNeeded];

[view mas_makeConstraints:^(MASConstraintMaker *make) {
    make.top.mas_equalTo(400);
    make.left.mas_equalTo(100);
    make.size.mas_equalTo(CGSizeMake(100, 100));
}];

//如果其約束還沒有生成的時候需要動畫的話,就請先強制刷新后才寫動畫,否則所有沒生成的約束會直接跑動畫
[view.superview layoutIfNeeded];

[UIView animateWithDuration:3 animations:^{
    [view mas_updateConstraints:^(MASConstraintMaker *make) {
        make.left.mas_equalTo(200);
    }];
    [view.superview layoutIfNeeded];//強制繪制
}];

后記

本篇主要說的就是一個小點,那就是使用Masonry做動畫的時候需要注意的事情,感興趣的給個贊或者關(guān)注~~~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容