技術: iOS Objective-C
概述
一個可以讓開發者通過編寫 tableView 的內容隨心所欲的定制自己想要的底部彈框
詳細
一. 運行效果圖
二. 實現過程
1. 實現一個有遮罩效果的半透明 view,然后添加一個可設置展示內容高度的 contentView
// 這個遮罩是可以遮住全屏 - (void)createUI{ self.frame = CGRectMake(0, 0, SS_ScreenW, SS_ScreenH); self.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.4]; self.userInteractionEnabled = YES; [self addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(disMissView)]]; [self.contentView addSubview:self.tbView]; } // contentView 是通過懶加載實現的 - (UIView *)contentView{ if (!_contentView) { _contentView = [UIView new]; _contentView.backgroundColor = [UIColor whiteColor]; _contentView.frame = CGRectMake(0, SS_ScreenH - _contentHeight - SS_BottomMargin, SS_ScreenW, _contentHeight + SS_BottomMargin); _contentView.opaque = YES; [self addSubview:_contentView]; } return _contentView; }
2. 我們實現的底部彈框實質上一個可滑動的表單(tableView),在 contentView 上添加一個 tableView
- (UITableView *)tbView{ if (!_tbView) { // _tbView = [[UITableView alloc]initWithFrame:CGRectZero style:UITableViewStyleGrouped]; _tbView = [UITableView new]; _tbView.delegate = self; _tbView.dataSource = self; [_tbView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"ss"]; } return _tbView; }
3. 通過設置UIView 動畫,實現遮罩 menuView 的展示和消失效果
// 將 menuView 展示在父 view 上 [view addSubview:self]; [view addSubview:self.contentView]; self.contentView.frame = CGRectMake(0, SS_ScreenH, SS_ScreenW, _contentHeight); __weak typeof(self) weakSelf = self; [UIView animateWithDuration:_animationDuration animations:^{ self.alpha = 1.0; self.contentView.frame = CGRectMake(0, SS_ScreenH - weakSelf.contentHeight - SS_BottomMargin, SS_ScreenW, weakSelf.contentHeight + SS_BottomMargin); } completion:^(BOOL finished) { }]; // 將 menuView 從父 view 上移除 __weak typeof(self) weakSelf = self; [UIView animateWithDuration:_animationDuration animations:^{ self.alpha = 0.0; self.contentView.frame = CGRectMake(0, SS_ScreenH, SS_ScreenW, weakSelf.contentHeight); } completion:^(BOOL finished) { [self removeFromSuperview]; [self.contentView removeFromSuperview]; }];
4. 實現選項和頭部的定制化
通過編寫自己的代理方法,讓開發人員根據自己項目的實際需要設置各個選項,並且可以定制固定的頭部以及底部
@protocol SSMenuViewDelegate <NSObject> @required; // 返回 tableView 的行數 - (NSInteger)menuTableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section; // 返回 tableViewCell 需要自定義 cell 的分割線 - (UITableViewCell *)menuTableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath; @optional; // 設置組數 - (NSInteger)menuNumberOfSectionsInTableView:(UITableView *)tableView; // 選中某個 tableView Cell - (void)menuTableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath; // 定義每個選項的cell的高度 - (CGFloat)menuTableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath; // 定義headerView - (UIView *)menuTableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section; // 定義headerView 的高度 - (CGFloat)menuTableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section; // 定義 footterView - (UIView *)menuTableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section; - (CGFloat)menuTableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section; @end
三. 項目結構
四. 使用手冊
1. 首先,根據目錄,將 SSMenuView.h, SSMenuView.m 文件,添加到自己項目中
2. 創建彈框控件
由於在使用類似彈框的時候,用戶可能會多次點擊使用,為了避免重復創建,建議使用懶加載創建一個彈窗控件
# pragma # pragma mark - Lazy - - (SSMenuView *)menuView{ if (!_menuView) { _menuView = [SSMenuView new]; _menuView.delegate = self; // _menuView.contentHeight = 44 * 6; // _menuView.tbView.separatorStyle = UITableViewCellSeparatorStyleNone; } return _menuView; }
3. 根據自己的項目需要,創建自己的彈框內容
# pragma # pragma mark - SSMenuViewDelegate - - (NSInteger)menuTableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ return 4; } - (UITableViewCell *)menuTableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cellID"]; if (!cell) { cell = [[UITableViewCell alloc]initWithStyle:(UITableViewCellStyleDefault) reuseIdentifier:@"cellID"]; } cell.textLabel.textAlignment = NSTextAlignmentCenter; cell.textLabel.text = [NSString stringWithFormat:@"這是選項%ld",indexPath.row]; cell.selectionStyle = UITableViewCellSelectionStyleNone; return cell; } - (CGFloat)menuTableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{ return 44; } - (CGFloat)menuTableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{ return 44; } - (UIView *)menuTableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section{ UIView *footer = [UIView new]; footer.backgroundColor = [UIColor orangeColor]; return footer; } - (UIView *)menuTableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{ UIView *header = [UIView new]; header.backgroundColor = [UIColor whiteColor]; header.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 44); UILabel *lab = [UILabel new]; lab.text = @"這是選項的頭部"; [header addSubview:lab]; lab.textAlignment = NSTextAlignmentCenter; lab.frame = header.frame; return header; }
4. 根據需要,在觸發點擊事件,彈出彈框
此處,有2種展示方式,根據開發者自己的需要選擇是否將彈框完全全屏
- (IBAction)click:(id)sender { // [self.menuView showInView:self.view]; [self.menuView showInWindow]; } // 隱藏彈框 [self.menuView disMissView];