UI学习:UITableView的基本操作及折叠cell

文章目录

UITableView

tableView 的本质是 一个高性能的滚动列表容器

基本协议方法

必须要实现两个协议:

objc 复制代码
<UITableViewDataSource> 
<UITableViewDelegate>

DataSource (数据源) 表示的是 "显示什么"

必须实现两个协议 (@required)

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section; 决定了每组有多少行的内容

objc 复制代码
// 设置每个section 有多少行
- (NSInteger) tableView: (UITableView*)tableView numberOFRowsInsection: (NSInteger) section {
    return 10; 
}

- (UITableViewCell*) tableView: (UITableView*) tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath; 设置单元格内容

objc 复制代码
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CellID" 
                                                            forIndexPath:indexPath];
    cell.textLabel.text = self.dataArray[indexPath.row];
    return cell;
}

Cell 的详细内容, 下文会详细讲解

可选实现:

objc 复制代码
// 设置组数
// 默认是 1 
- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView {
    return 2;
} 

设置行高, 这里指的还是每一个cell的高度

objc 复制代码
// 设置行高
- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return 100;
}

设置头标题

objc 复制代码
// 头标题
- (NSString*) tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    return @"title of head";
}

效果图:

设置尾标题

objc 复制代码
// 尾标题
- (NSString*) tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section {
    return @"title of tail";
} 

效果如下

另外,和可以调整头部标题和尾部标题的高度

objc 复制代码
// 获取头部高度
- (CGFloat) tableView: (UITableView*) tableView heightForHeaderInSection:(NSInteger)section {
    return 100;
}

// 尾部高度
- (CGFloat) tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
    return 200;
}

DataSource = 提供数据 + 创建 Cell

Delegate (代理) 决定的是 "怎么交互"

常用的方法有:

objc 复制代码
// 行被点击的时候调用的方法
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
    NSLog(@"选中了 %ld %ld", indexPath.section, indexPath.row); 
} 

// 取消选中(切换选中时调用)
- (void) tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
    NSLog(@"取消选中单元格: %ld %ld", indexPath.section, indexPath.row);
} 

效果如下

添加图片(Image)

需要在- (UITableViewCell*) tableView: (UITableView*) tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;方法中先创建一个Image对象,然后用创建的Image对象赋值给UITableView的ImageView.image;

objc 复制代码
- (nonnull UITableViewCell *)tableView:(nonnull UITableView *)tableView cellForRowAtIndexPath:(nonnull NSIndexPath *)indexPath { 
    
    UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier: @"cellID" forIndexPath: indexPath];
    cell.textLabel.text = _dataArray[indexPath.row];
    UIImage* image = [UIImage imageNamed: [NSString stringWithFormat: @"%ld.jpg", indexPath.row]];
    cell.imageView.image = image;
    return cell;
}

折叠Cell

添加一个isExpand 属性用来记录cell的展开状态

objc 复制代码
@interface ViewController ()
@property (nonatomic) BOOL isExpanded; // 记录展开状态
@end

然后需要修改- (NSInteger)tableView:(**nonnull** UITableView *)tableView numberOfRowsInSection:(NSInteger)section方法的实现部分, 根据cell是否展开来动态调整行数

objc 复制代码
// 展开返回真实数量, 折叠返回 0
- (NSInteger)tableView:(nonnull UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return _isExpanded == YES ? _dataArray.count : 0;
}

自定义head, 替换原来的titleForHeaderInSection, 将HeadView 设置为一个button, 可以直接通过按钮调用事件来控制cell的展开

objc 复制代码
- (UIView*) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    UIButton* btn = [UIButton buttonWithType: UIButtonTypeSystem];
    btn.backgroundColor = [UIColor systemBlueColor];
    // 对齐方式: 左对齐
    btn.contentHorizontalAlignment  = UIControlContentHorizontalAlignmentLeft;
    
    // 箭头跟着状态改变
    NSString* arrow = _isExpanded ? @" ^ " : @" > ";    // 点击head切换状态
    [btn setTitle: [NSString stringWithFormat: @"%@This is title of head", arrow] forState: UIControlStateNormal];
    [btn setTitleColor: [UIColor whiteColor] forState: UIControlStateNormal];
    
    [btn addTarget: self action: @selector(headerTapped:) forControlEvents: UIControlEventTouchUpInside];
    return btn;
}

按钮事件, 每次点击都改变 isExpanded, 然后重新加载每一组的内容, 并且刷新cell的内容

objc 复制代码
- (void) headerTapped: (UIButton*) sender {
    _isExpanded = !_isExpanded;
    
//    刷新 UITableView 的第 0 组(第一组)数据,并且用淡入淡出的动画效果更新
    [_tableView reloadSections: [NSIndexSet indexSetWithIndex: 0] withRowAnimation: UITableViewRowAnimationFade];
}

运行效果如下:

相关推荐
kkkkkkkkkk_Z25 分钟前
新手自学嵌入式 | 学习日记:I2C总线协议、时序分析、读写流程与代码实现
学习
Cx330❀2 小时前
深入浅出 Qt 绘图机制:从 QPainter 到四大图像类解析
开发语言·qt·ui·性能优化·图形渲染
鬼手点金2 小时前
构建有效 Agent 的核心原则
java·人工智能·git·学习·自动化
姜九笙5613 小时前
python学习---归来仍是新人
java·python·学习
海绵宝宝转agent3 小时前
2026-10-19学习笔记
笔记·学习
云水初3 小时前
【agent篇】RAG Agent避坑指南(附高级RAG Agent汇总)
开发语言·笔记·python·学习·langchain·agent·rag
外收内放3 小时前
数据分析(图表信息详解)
python·学习·数据分析·matplotlib
气质、小青年!4 小时前
进程1学习
linux·学习
坤坤子吖4 小时前
Linux 线程同步与互斥——互斥锁
linux·服务器·c++·笔记·学习
撩得Android一次心动4 小时前
Jetpack Compose 知识点整理3【个人用】
android·笔记·学习·kotlin·android compose