如何在iOS应用中用Objective-C实现带TableView的弹出视图功能?

问题解答:弹出视图识别与Objective-C实现方案
嘿,我来帮你一步步解决这个问题~
一、这个弹出视图是什么?
你截图里的弹出视图,最常见的是系统原生的UIAlertController(设置为UIAlertControllerStyleActionSheet样式),也就是我们常说的「操作表弹窗」。它自带底部弹出的动画、选项选择交互,完全能满足你描述的“选选项改导航栏标题/TableView内容”的需求。
如果需要更复杂的自定义样式(比如选项带图标、多行文本),也可以自己实现一个带TableView的自定义弹窗,自由度会更高。
二、如何在该视图中添加或显示TableView?
分两种常用方案:
1. 给系统UIAlertController嵌入TableView
系统的ActionSheet本身没有TableView,但可以创建一个UITableViewController,把它设置为UIAlertController的内容控制器,这样弹窗里就会显示TableView了,既保留系统弹窗的动画和交互,又能实现列表选择。
2. 自定义带TableView的弹出弹窗
自己创建一个容器View,里面直接添加TableView和取消按钮,再通过动画实现从底部弹出的效果,这种方式可以完全自定义弹窗的样式、尺寸、交互逻辑。
三、Objective-C实现代码示例
方案1:系统UIAlertController嵌入TableView
第一步:创建自定义TableViewController
先写一个带代理的TableViewController,用来处理选项列表和选择回调:
// CustomTableViewController.h #import <UIKit/UIKit.h> @protocol CustomTableViewControllerDelegate <NSObject> - (void)didSelectOptionAtIndex:(NSInteger)index; @end @interface CustomTableViewController : UITableViewController @property (nonatomic, weak) id<CustomTableViewControllerDelegate> delegate; @property (nonatomic, strong) NSArray *options; // 选项数组 @end // CustomTableViewController.m #import "CustomTableViewController.h" @implementation CustomTableViewController - (void)viewDidLoad { [super viewDidLoad]; self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero]; // 隐藏空行 } // 返回选项数量 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return self.options.count; } // 配置单元格 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *cellID = @"OptionCell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID]; if (!cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID]; cell.selectionStyle = UITableViewCellSelectionStyleGray; } cell.textLabel.text = self.options[indexPath.row]; return cell; } // 处理选项选择 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [tableView deselectRowAtIndexPath:indexPath animated:YES]; if ([self.delegate respondsToSelector:@selector(didSelectOptionAtIndex:)]) { [self.delegate didSelectOptionAtIndex:indexPath.row]; } [self dismissViewControllerAnimated:YES completion:nil]; } @end
第二步:在主ViewController中调用弹窗
在你的主页面(带两个导航栏和TableView的控制器)里,给第二个导航栏的按钮添加点击事件:
// 主ViewController的按钮点击方法 - (IBAction)showPopupBtnTapped:(UIButton *)sender { // 1. 初始化自定义TableVC,传入选项数据 CustomTableViewController *tableVC = [[CustomTableViewController alloc] initWithStyle:UITableViewStylePlain]; tableVC.options = @[@"选项A", @"选项B", @"选项C"]; tableVC.delegate = self; // 2. 创建系统ActionSheet样式的AlertController UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:@"请选择" message:nil preferredStyle:UIAlertControllerStyleActionSheet]; // 把TableVC嵌入AlertController [alertVC setValue:tableVC forKey:@"contentViewController"]; // 添加取消按钮 UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil]; [alertVC addAction:cancelAction]; // 适配iPad(如果需要) alertVC.popoverPresentationController.sourceView = sender; alertVC.popoverPresentationController.sourceRect = sender.bounds; // 弹出弹窗 [self presentViewController:alertVC animated:YES completion:nil]; } // 实现代理方法,处理选择逻辑 - (void)didSelectOptionAtIndex:(NSInteger)index { static BOOL isFirstSelect = YES; // 标记是否是第一次选择 NSArray *options = @[@"选项A", @"选项B", @"选项C"]; if (isFirstSelect) { // 第一次选择:修改导航栏标题 self.navigationItem.title = options[index]; isFirstSelect = NO; } else { // 后续选择:更新TableView内容 self.mainTableData = [self getTableDataForIndex:index]; // mainTableData是你主页面TableView的数据源 [self.mainTableView reloadData]; } } // 模拟根据选项获取对应的TableView数据 - (NSArray *)getTableDataForIndex:(NSInteger)index { switch (index) { case 0: return @[@"A类内容1", @"A类内容2", @"A类内容3"]; case 1: return @[@"B类内容1", @"B类内容2"]; case 2: return @[@"C类内容1", @"C类内容2", @"C类内容3", @"C类内容4"]; default: return @[]; } }
方案2:自定义带TableView的弹出弹窗
如果不想依赖系统AlertController,完全自定义弹窗:
// 主ViewController中 #define POPUP_HEIGHT 260.0f // 弹窗高度 - (IBAction)showCustomPopupBtnTapped:(UIButton *)sender { // 1. 创建遮罩层 UIView *maskView = [[UIView alloc] initWithFrame:self.view.bounds]; maskView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5]; maskView.tag = 1001; // 点击遮罩关闭弹窗 UITapGestureRecognizer *tapMask = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideCustomPopup)]; [maskView addGestureRecognizer:tapMask]; [self.view addSubview:maskView]; maskView.alpha = 0.0; // 2. 创建弹窗容器 UIView *popupView = [[UIView alloc] initWithFrame:CGRectMake(0, self.view.bounds.size.height, self.view.bounds.size.width, POPUP_HEIGHT)]; popupView.backgroundColor = [UIColor whiteColor]; popupView.layer.cornerRadius = 12.0f; popupView.clipsToBounds = YES; popupView.tag = 1002; [self.view addSubview:popupView]; // 3. 添加TableView到弹窗 UITableView *popupTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, popupView.bounds.size.width, POPUP_HEIGHT - 55)]; popupTableView.dataSource = self; popupTableView.delegate = self; popupTableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero]; [popupView addSubview:popupTableView]; // 4. 添加取消按钮 UIButton *cancelBtn = [[UIButton alloc] initWithFrame:CGRectMake(0, POPUP_HEIGHT - 55, popupView.bounds.size.width, 55)]; [cancelBtn setTitle:@"取消" forState:UIControlStateNormal]; [cancelBtn setTitleColor:[UIColor systemBlueColor] forState:UIControlStateNormal]; [cancelBtn addTarget:self action:@selector(hideCustomPopup) forControlEvents:UIControlEventTouchUpInside]; [popupView addSubview:cancelBtn]; // 5. 动画弹出弹窗 [UIView animateWithDuration:0.35 animations:^{ maskView.alpha = 1.0; popupView.frame = CGRectMake(0, self.view.bounds.size.height - POPUP_HEIGHT, self.view.bounds.size.width, POPUP_HEIGHT); }]; } // 关闭自定义弹窗 - (void)hideCustomPopup { UIView *popupView = [self.view viewWithTag:1002]; UIView *maskView = [self.view viewWithTag:1001]; [UIView animateWithDuration:0.35 animations:^{ maskView.alpha = 0.0; popupView.frame = CGRectMake(0, self.view.bounds.size.height, self.view.bounds.size.width, POPUP_HEIGHT); } completion:^(BOOL finished) { [popupView removeFromSuperview]; [maskView removeFromSuperview]; }]; } // TableView数据源方法 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return self.options.count; // self.options是你的选项数组,比如@[@"选项A", @"选项B", @"选项C"] } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *cellID = @"CustomPopupCell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID]; if (!cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID]; } cell.textLabel.text = self.options[indexPath.row]; return cell; } // TableView代理方法:处理选项选择 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [tableView deselectRowAtIndexPath:indexPath animated:YES]; static BOOL isFirstSelect = YES; if (isFirstSelect) { self.navigationItem.title = self.options[indexPath.row]; isFirstSelect = NO; } else { self.mainTableData = [self getTableDataForIndex:indexPath.row]; [self.mainTableView reloadData]; } [self hideCustomPopup]; }
内容的提问来源于stack exchange,提问作者Priyanka Patil
相关产品推荐
相关产品推荐

