You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:50:00