从0到1学习iOS

iOS cover与board动画效果的封装

2019-06-18  本文已影响0人  一粒咸瓜子

dependence on <NerdyUI>
UIViewController+Cover.h:

//  UIViewController+Cover.h
#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

typedef NS_ENUM(NSUInteger, kBoardContentMode) {
    kBoardContentModeBottom,
    kBoardContentModeCenter,
};

@interface UIViewController (Cover)

@property (nonatomic, readonly ,weak) UIView *cover;

- (void)setBoard:(UIView *)board contentMode:(kBoardContentMode)mode margin:(CGFloat)margin;

- (void)coverShowUp;
- (void)coverDisappear;

@end
NS_ASSUME_NONNULL_END

UIViewController+Cover.m:

#import "UIViewController+Cover.h"

static void *coverKey = @"coverKey";
static void *boardKey = @"boardKey";
static void *modeKey = @"modeKey";
static void *bottomMarginKey = @"bottomMarginKey";

@implementation UIViewController (Cover)

- (UIView *)cover {
    return objc_getAssociatedObject(self, coverKey);
}


- (void)setBoard:(UIView *)board contentMode:(kBoardContentMode)mode margin:(CGFloat)margin {
    UIView *cover = View.bgColor(@"black, 0.6");
    board.addTo(cover);
    
    if (mode == kBoardContentModeCenter) {
        board.makeCons(^{
            make.center.equal.superview.constants(0);
        });
    } else {
        board.makeCons(^{
            make.centerX.equal.superview.constants(0);
            make.bottom.equal.superview.constants(-margin);
        });
    }
    
    cover.alpha = 0;
    board.alpha = 0;
    
    objc_setAssociatedObject(board, modeKey, @(mode), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    objc_setAssociatedObject(board, bottomMarginKey, @(margin), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    objc_setAssociatedObject(self, boardKey, board, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    objc_setAssociatedObject(self, coverKey, cover, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}


- (void)coverShowUp {
    UIView *cover = objc_getAssociatedObject(self, coverKey);
    UIView *board = objc_getAssociatedObject(self, boardKey);
    cover.embedIn(UIApplication.sharedApplication.keyWindow);
    
    kBoardContentMode mode = [objc_getAssociatedObject(board, modeKey) integerValue];
    if (mode == kBoardContentModeCenter) {
        [UIView animateWithDuration:0.3 animations:^{
            board.alpha = 1;
            cover.alpha = 1;
        }];
    } else {
        CGFloat h = board.h;
        if (h <= 0) {
            [board layoutIfNeeded];
            h = board.h;
        }
        
        CGFloat margin = [objc_getAssociatedObject(board, bottomMarginKey) floatValue];
        board.transform = CGAffineTransformMakeTranslation(0, h + margin);
        [UIView animateWithDuration:0.3 animations:^{
            board.transform = CGAffineTransformIdentity;
            board.alpha = 1;
            cover.alpha = 1;
        }];
    }
}


- (void)coverDisappear {
    UIView *cover = objc_getAssociatedObject(self, coverKey);
    UIView *board = objc_getAssociatedObject(self, boardKey);
    
    kBoardContentMode mode = [objc_getAssociatedObject(board, modeKey) integerValue];
    if (mode == kBoardContentModeCenter) {
        [UIView animateWithDuration:0.3 animations:^{
            cover.alpha = 0;
            board.alpha = 0;
        } completion:^(BOOL finished) {
            [board removeFromSuperview];
            [cover removeFromSuperview];
        }];
        
    } else {
        CGFloat h = board.h;
        if (h <= 0) {
            [board layoutIfNeeded];
            h = board.h;
        }
        
        CGFloat margin = [objc_getAssociatedObject(board, bottomMarginKey) floatValue];
        [UIView animateWithDuration:0.3 animations:^{
            board.transform = CGAffineTransformMakeTranslation(0, h + margin);
            cover.alpha = 0;
            board.alpha = 0;
        } completion:^(BOOL finished) {
            [board removeFromSuperview];
            [cover removeFromSuperview];
        }];
    }
}
@end

注意:若要在初始化时使用,需在能够获取到keywindow的时机之后调用相关方法。可在调用coverShowUp的时候用dispatch_async( dispatch_get_main_queue(),^{})包一下。
原因:在程序初始化时,只有在根控制器的- viewDidAppear:中才可获取到keyWindow。可用上述方法来获取合适的调用时机。

附上代码:

- (void)viewDidLoad {
    [super viewDidLoad];
    NSLog(@"%s, %@",__func__, UIApplication.sharedApplication.keyWindow);
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    NSLog(@"%s, %@",__func__, UIApplication.sharedApplication.keyWindow);
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    NSLog(@"%s, %@",__func__, UIApplication.sharedApplication.keyWindow);
}

Output:
-[ViewController viewDidLoad], (null)
-[ViewController viewWillAppear:], (null)
-[ViewController viewDidAppear:], <UIWindow: 0x13be125c0; frame = (0 0; 375 667); gestureRecognizers = <NSArray: 0x282a38b10>; layer = <UIWindowLayer: 0x28245e680>>
上一篇 下一篇

猜你喜欢

热点阅读