美文网首页从0到1学习iOS
iOS cover与board动画效果的封装

iOS cover与board动画效果的封装

作者: 一粒咸瓜子 | 来源:发表于2019-06-18 15:58 被阅读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>>
    

    相关文章

      网友评论

        本文标题:iOS cover与board动画效果的封装

        本文链接:https://www.haomeiwen.com/subject/dsvfqctx.html