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>>
网友评论