一、自定义蒙版--封装控件,先想好外界怎么来调用,根据外界调用的方法,然后进入内部实现
- 在外部,调用蒙版的方法--[ChaosCover show]; [ChaosCover hide];
- 内部实现
1 #import "ChaosCover.h" 2 3 @implementation ChaosCover 4 + (void)show 5 { 6 // 创建HUD 7 ChaosCover *cover = [[ChaosCover alloc] initWithFrame:ChaosScreenBounds]; 8 cover.backgroundColor = [UIColor blackColor]; 9 cover.alpha = 0.5; 10 // 添加到主窗口上 11 [ChaosKeyWindow addSubview:cover]; 12 } 13 14 + (void)hide 15 { 16 // 遍历主窗口的子控件,找出HUD 17 for (UIView *childView in ChaosKeyWindow.subviews) { 18 if ([childView isKindOfClass:self]) { 19 [childView removeFromSuperview]; 20 } 21 } 22 } 23 @end
二、封装活动菜单--在蒙版上显示,点击叉叉,动画形式消失在左上角
- 使用xib描述了活动菜单的内容
- 外部的调用也是显示 和隐藏(动画形式)两个方法,此外 外部还要监听叉叉的点击。动画完成后模仿了系统动画完成传递block的方法来解决

1 @implementation ChaosActiveMenu 2 - (IBAction)closeBtn:(id)sender { 3 if ([_delegate respondsToSelector:@selector(activeMenuDidClickClose:)]) { 4 [_delegate activeMenuDidClickClose:self]; 5 } 6 } 7 8 // 封装类方法,让隐藏的点由外部决定 9 + (void)hideInpoint:(CGPoint)point completion:(void(^)())completion 10 { 11 for (ChaosActiveMenu *childView in ChaosKeyWindow.subviews) { 12 if ([childView isKindOfClass:self]) { 13 [childView setUpHideAnimationWithPoint:point completion:completion]; 14 } 15 } 16 17 } 18 19 // 根据点坐标,设置隐藏的动画 20 - (void)setUpHideAnimationWithPoint:(CGPoint)point completion:(void(^)())completion 21 { 22 [UIView animateWithDuration:0.5 animations:^{ 23 24 CGAffineTransform translate = CGAffineTransformMakeTranslation( -self.center.x + 44, -self.center.y + 44); 25 CGAffineTransform translateScale = CGAffineTransformScale(translate, 0.01, 0.01); 26 self.transform = translateScale; 27 28 } completion:^(BOOL finished) { 29 // HUD 移除 30 [self removeFromSuperview]; 31 if (completion) { 32 completion(); 33 } 34 }]; 35 36 } 37 38 // 根据点坐标显示activeMenu 39 + (instancetype)showInPoint:(CGPoint)point 40 { 41 // 显示活动的图片 42 ChaosActiveMenu *menu = [ChaosActiveMenu activeMenu]; 43 menu.center = point; 44 [ChaosKeyWindow addSubview:menu]; 45 return menu; 46 } 47 48 49 + (instancetype)activeMenu 50 { 51 return [[NSBundle mainBundle] loadNibNamed:NSStringFromClass([ChaosActiveMenu class]) owner:nil options:nil][0]; 52 } 53 @end
- 在运用block的时候遇到了点问题,自己对block运用的是不很熟练
三、自定义下拉菜单--带弹簧效果。
--行数计算公式 row = (count - 1) / cols + 1;九宫格布局应该经常用
--分割线的巧妙添加
--自己做动画方面不足,通过这个例子学到了,先利用transform将空间平移,之后通过取消平移downMenu.transform = CGAffineTransformIdentity;来做动画

1 @interface ChaosDownMenu () 2 /** items */ 3 @property(nonatomic,strong) NSArray *items; 4 /** 子控件按钮集合 */ 5 @property(nonatomic,strong) NSMutableArray *btnArray; 6 @end 7 8 @implementation ChaosDownMenu 9 10 - (NSMutableArray *)btnArray 11 { 12 if (_btnArray == nil) { 13 _btnArray = [NSMutableArray array]; 14 } 15 return _btnArray; 16 } 17 18 #pragma mark - 隐藏downMenu的方法 19 - (void)hide 20 { 21 [UIView animateWithDuration:0.3 animations:^{ 22 23 self.transform = CGAffineTransformMakeTranslation(0, -self.height); 24 25 } completion:^(BOOL finished) { 26 27 [self removeFromSuperview]; 28 }]; 29 } 30 31 #pragma mark - 根据坐标点 和 子控件按钮的模型集合 初始化 32 + (instancetype)showInView:(UIView *)superView point:(CGPoint)point items:(NSArray *)items 33 { 34 NSInteger count = items.count; 35 36 if (count % 3) { // 模型个数不是3的倍数 37 NSException *exc = [NSException exceptionWithName:@"items个数不符合" reason:@"items的个数必须是3的倍数" userInfo:nil]; 38 [exc raise]; 39 } 40 41 // 行数计算公式 row = (count - 1) / cols + 1 42 NSInteger row = (count - 1) / ChaosCols + 1; 43 44 ChaosDownMenu *downMenu = [[ChaosDownMenu alloc] init]; 45 46 downMenu.items = items; 47 48 // ChaosScreenBounds.size.width height:row * itemWH 49 downMenu.frame = CGRectMake(point.x, point.y, ChaosScreenBounds.size.width, row * ChaosItemWH); 50 51 downMenu.backgroundColor = [UIColor blackColor]; 52 53 // 添加所有子控件 54 [downMenu setUpAllBtns:items]; 55 56 // 添加分割线 57 [downMenu setUpDivideView]; 58 59 // 添加黑色的view,防止动画的时候漏出后面父控件的白色 60 UIView *blackView = [[UIView alloc] initWithFrame:downMenu.frame]; 61 62 blackView.backgroundColor = [UIColor blackColor]; 63 64 [superView addSubview:blackView]; 65 66 [superView addSubview:downMenu]; 67 68 // 动画--首先让menu平移上去 69 downMenu.transform = CGAffineTransformMakeTranslation(0, -(row * ChaosItemWH)); 70 71 [UIView animateWithDuration:0.5 delay:0 usingSpringWithDamping:0.3 initialSpringVelocity:10 options:UIViewAnimationOptionCurveEaseInOut animations:^{ 72 73 downMenu.transform = CGAffineTransformIdentity; 74 75 } completion:^(BOOL finished) { 76 77 [blackView removeFromSuperview]; 78 79 }]; 80 return downMenu; 81 } 82 83 - (void)setUpDivideView 84 { 85 // 添加纵向分割线 86 // 纵向分割线的数目 87 NSInteger colsViewCount = ChaosCols - 1; 88 // 纵向分割线的xywh 89 for (int i = 0; i <colsViewCount; i++) { 90 UIView *view = [[UIView alloc] init]; 91 view.frame = CGRectMake((i + 1) * ChaosItemWH, 0, 1, self.height); 92 view.backgroundColor = [UIColor whiteColor]; 93 [self addSubview:view]; 94 } 95 // 添加横向分割线 96 // 横向分割线条数 97 NSInteger rowViewCount = (self.items.count - 1) / ChaosCols; 98 for (int i = 0; i < rowViewCount; i++) { 99 100 UIView *view = [[UIView alloc] init]; 101 view.frame = CGRectMake(0, (i + 1) * ChaosItemWH, self.width, 1); 102 view.backgroundColor = [UIColor whiteColor]; 103 [self addSubview:view]; 104 } 105 } 106 107 #pragma mark - 添加子控件 108 - (void)setUpAllBtns:(NSArray *)items 109 { 110 for (ChaosMenuItem *item in items) { 111 UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; 112 [btn setTitle:item.title forState:UIControlStateNormal]; 113 [btn setImage:item.image forState:UIControlStateNormal]; 114 btn.backgroundColor = [UIColor blackColor]; 115 [self.btnArray addObject:btn]; 116 [self addSubview:btn]; 117 } 118 } 119 120 #pragma mark - 布局子控件 121 - (void)layoutSubviews 122 { 123 [super layoutSubviews]; 124 125 CGFloat x = 0; 126 CGFloat y = 0; 127 for (int i = 0; i < self.btnArray.count; i ++) { 128 UIButton *btn = self.btnArray[i]; 129 int rowNO = i / ChaosCols; 130 int colsNO = i % ChaosCols; 131 x = colsNO * ChaosItemWH; 132 y = rowNO * ChaosItemWH; 133 btn.frame = CGRectMake(x, y, ChaosItemWH, ChaosItemWH); 134 } 135 } 136 137 @end