问题描述
- 今天写项目写一个下拉菜单,第一次下拉之后,再点一下可以移除,但是再点一下应该可以继续下拉出来但是就是不出来了。
解决思路
- 经过检查可以移除视图,但是downMenu一直有值,经过在经过断点调试发现并没有销毁。这时就应该想到为什么呢?此时回头看属性,发现是strong,因为在ARC中没有强引用的对象才会被销毁,虽然视图销毁了,但是我们控制器依然引用了它,所有没有销毁。
- 此时我们有两种解决方法,一种就是用weak,一种就是在调用隐藏之后,给属性赋值为nil.
1 #pragma mark - 是否下拉菜单 2 - (void)downDrapView 3 { 4 if (self.popMenu == NO) { 5 6 [self downMenu]; 7 8 9 NSLog(@"%@",self.downMenu); 10 }else{ 11 12 [self.downMenu hide]; 13 14 self.downMenu = nil; 15 16 } 17 _popMenu = !_popMenu; 18 19 20 }
误区
- 在我们正常思维下,移除视图之后,肯定会重新创建下,但是事实并没有。
(图1)
(图2)
(图3)
@interface SAMHallViewController ()<SAMActiveMenuDelegate> /** 判断是下拉还是隐藏 */ @property (nonatomic, assign) BOOL popMenu; /** downMenu */ #warning 这里面要用weak要不然移除视图之后对象还是依然在,永远不会新建 @property (nonatomic, strong) SAMDownMenu *downMenu; @end
- (SAMDownMenu *)downMenu { if (_downMenu == nil) { SAMMenuItem *item = [SAMMenuItem menuItemWithTitle:nil withImage:[UIImage imageNamed:@"Development"]]; SAMMenuItem *item1 = [SAMMenuItem menuItemWithTitle:nil withImage:[UIImage imageNamed:@"Development"]]; SAMMenuItem *item2 = [SAMMenuItem menuItemWithTitle:nil withImage:[UIImage imageNamed:@"Development"]]; SAMMenuItem *item3 = [SAMMenuItem menuItemWithTitle:nil withImage:[UIImage imageNamed:@"Development"]]; SAMMenuItem *item4 = [SAMMenuItem menuItemWithTitle:nil withImage:[UIImage imageNamed:@"Development"]]; SAMMenuItem *item5 = [SAMMenuItem menuItemWithTitle:nil withImage:[UIImage imageNamed:@"Development"]]; NSArray *items = @[item,item1,item2,item3,item4,item5]; _downMenu = [SAMDownMenu showInView:self.view items:items oriY:0]; } return _downMenu; }
#pragma mark - 是否下拉菜单 - (void)downDrapView { if (self.popMenu == NO) { [self downMenu]; NSLog(@"%@",self.downMenu); }else{ [self.downMenu hide]; } _popMenu = !_popMenu;
+ (instancetype)showInView:(UIView *)superView items:(NSArray *)items oriY:(CGFloat)oriY { NSUInteger count = items.count; //用来提醒开发者items里面元素个数传进来的应该是3的倍数 if (count % 3) { [NSException exceptionWithName:@"items的总数不符合要求" reason:@"传入数组内的元素必须为3的倍数" userInfo:nil]; } CGFloat x = 0; CGFloat row = count / kCols; CGFloat menuH = row * WH; SAMDownMenu *menu = [[self alloc] init]; menu.frame = CGRectMake(x, oriY, SAMScreenBounds.size.width, menuH); //创建占位视图,要不然下拉会有段真空白 UIView *blockView = [[UIView alloc] initWithFrame:menu.frame]; blockView.backgroundColor = [UIColor blackColor]; [superView insertSubview:blockView belowSubview:menu]; //给模型赋值传到下面的,调用懒加载 menu.items = items; [menu setUpAllBtns]; [menu addAllLines]; menu.transform = CGAffineTransformMakeTranslation(0, -menu.height); // 动画下拉菜单窗口 [UIView animateWithDuration:0.5 delay:0 usingSpringWithDamping:0.5 initialSpringVelocity:0 options:UIViewAnimationOptionCurveLinear animations:^{ menu.transform = CGAffineTransformIdentity; } completion:^(BOOL finished) { [blockView removeFromSuperview]; }]; menu.backgroundColor = [UIColor blackColor]; [superView addSubview:menu]; return menu; }
#pragma mark - 添加所有中间间隔线 - (void)addAllLines { for (int i = 0; i < kCols - 1; i++) { CGFloat x = (i + 1) * WH; UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(x, 0, 1, self.height)]; lineView.backgroundColor = [UIColor whiteColor]; [self addSubview:lineView]; } UIView * lineView = [[UIView alloc] initWithFrame:CGRectMake(0, WH, self.width, 1)]; lineView.backgroundColor = [UIColor whiteColor]; [self addSubview:lineView]; }
#pragma mark - 记录所有item - (void)setUpAllBtns { for (NSUInteger i = 0; i < self.items.count; i++) { UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; SAMMenuItem *item = self.items[i]; [btn setTitle:item.title forState:UIControlStateNormal]; [btn setImage:item.image forState:UIControlStateNormal]; [self addSubview:btn]; // 用一个数组存放每一个btn [self.btns addObject:btn]; } }
#pragma mark - 计算子控件button里面的位置 - (void)layoutSubviews { [super layoutSubviews]; CGFloat x = 0; CGFloat y = 0; CGFloat col = 0; //这个要用整数,要不然会成为电梯形的而局 int row = 0; NSUInteger count = self.btns.count; for (NSUInteger i = 0; i < count; i++) { UIButton *btn = _btns[i]; col = i % kCols; row = (int)i / kCols; x = col * WH; y = row * WH; btn.frame = CGRectMake(x, y, WH, WH); } }
#pragma mark - 动画隐藏并移除视图 - (void)hide { [UIView animateWithDuration:0.5 animations:^{ self.transform = CGAffineTransformMakeTranslation(0, -self.height); } completion:^(BOOL finished) { [self removeFromSuperview]; }]; }