技術: 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];
