Ui学习--UITableView

2024-06-16 16:52
文章标签 学习 ui uitableview

本文主要是介绍Ui学习--UITableView,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

UI学习

  • UITableView基础
  • UITableView协议
  • UITableView高级协议与单元格
  • 总结


UITableView基础

UITableView作为iOS中的一个控件,用于以表格形式展示数据。例如通讯录好友,朋友圈信息等,都是UITableView的实际运用场景。
首先我们先要加入两个协议:UITableViewDelegate,UITableViewDataSource
在这两个协议中,有必须实现的四个协议方法:

  1. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section :获取每组元素的个数
  2. -(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView:获取每组元素的行数
  3. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath:创建单元格对象函数。

然后我们现在接口文件中添加协议和UITableView对象


#import <UIKit/UIKit.h>@interface ViewController : UIViewController
<
//实现数据视图的普通协议
//数据视图的普通事件处理
UITableViewDelegate,
//实现数据视图的数据代理协议
//实现数据视图的数据代理
UITableViewDataSource
>
{//定义一个数据视图对象//数据视图用来显示大量相同格式的大量信息的视图//例如:电话通讯录,QQ好友,朋友圈信息//相同格式信息内容不同UITableView *_tablelView;
}@end

然后我们在实现部分创建数据视图并实现协议函数


#import "ViewController.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view.//创建数据视图,传入两个参数//参一:数据视图的位置//参二:数据视图的风格//UITableViewStylePlain:普通风格//UITableViewStyleGrouped:分组风格_tablelView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStyleGrouped];//设置数据视图的代理对象_tablelView.delegate = self;//设置数据视图的数据源对象_tablelView.dataSource = self;[self.view addSubview:_tablelView];
}//获取每组元素的个数(行数)
//必须要实现的协议函数
//程序在显示数据视图是会调用此函数
//返回值:表示每组元素的个数
//P1:数据视图对象本身
//P2:哪一组需要的行数
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{return 6;
}-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView
{return 4;
}//创建单元格对象函数- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{NSString *cellStr = @"cell";UITableViewCell *cell = [_tablelView dequeueReusableCellWithIdentifier:cellStr];if (cell == nil) {//创建一个单元格对象//参一:单元格的样式//参二:单元格的复用标记cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellStr];}NSString *str = [NSString stringWithFormat:@"第%ld组,第%ld行", indexPath.section, indexPath.row];//将单元格的主文字内容赋值cell.textLabel.text = str;return cell;
}
@end

效果:
在这里插入图片描述


UITableView协议

我们在此处学习如下几个协议:

  1. - (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath:获取单元格高度
  2. -(NSString*) tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section:获取每组头部标题
  3. -(NSString*) tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section:获取每组尾部标题
  4. - (CGFloat) tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section:获取头部高度
  5. -(CGFloat) tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section:获取尾部高度

我们省略接口部分,给出实现部分并将上述协议实现:


#import "ViewController.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view.//创建数据视图对象_tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStyleGrouped];//设置代理对象_tableView.delegate = self;//设置数据代理对象_tableView.dataSource = self;//数据视图显示[self.view addSubview:_tableView];//创建一个可变数组_arrayData = [[NSMutableArray alloc] init];for (int i = 'A'; i <= 'Z'; i++) {//定义小数组NSMutableArray *arraySmall = [[NSMutableArray alloc] init];for (int j = 1; j <= 5 ; j++) {NSString *str = [NSString stringWithFormat:@"%c%d", i, j];[arraySmall addObject:str];}//生成一个二维数组[_arrayData addObject:arraySmall];}
}//获取组数
-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView
{return _arrayData.count;
}//获取每组的元素个数
-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{NSInteger numRow = [[_arrayData objectAtIndex:section] count];return numRow;
}-(UITableViewCell*) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{NSString *str = @"cell";UITableViewCell *cell = [_tableView dequeueReusableCellWithIdentifier:str];if (cell == nil) {cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:str];}cell.textLabel.text = _arrayData[indexPath.section][indexPath.row];return cell;
}//获取高度
- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{return 100;
}//获取每组头部标题
-(NSString*) tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{return @"哈哈!";
}//获取每组尾部标题
-(NSString*) tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section
{return @"尾巴哈哈";
}//获取头部高度
- (CGFloat) tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{return 40;
}//获取尾部高度
-(CGFloat) tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{return 60;
}@end

注意:这些协议函数是可选择实现的
效果:
在这里插入图片描述


UITableView高级协议与单元格

我们在此处学习以下高级协议:

  1. - (UITableViewCellEditingStyle) tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath:单元格显示效果协议
  2. - (void) tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath:当手指在单元格上移动时,显示编辑状态
  3. - (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath:选中单元格
  4. -(void) tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath:取消所选单元格,需要在已选择单元格后再选另一单元格后调用。

我们先在接口文件中创建对象,并在SceneDelegate文件里添加导航控制器。

#import <UIKit/UIKit.h>@interface ViewController : UIViewController
<UITableViewDelegate,
UITableViewDataSource
>{//数据视图UITableView *_tableView;//数据源NSMutableArray* _arrayData;//添加导航按钮UIBarButtonItem *btnEdit;UIBarButtonItem *btnFinish;UIBarButtonItem *btnDelete;//设置编辑状态BOOL isEdit;
}
@end

然后,我们在实现部分中,完成对导航栏按钮的创建。并且实现高级协议。


#import "ViewController.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view._tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];//自动调整子视图大小_tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;//设置代理_tableView.delegate = self;_tableView.dataSource = self;//数据视图的头部视图的设定_tableView.tableHeaderView = nil;//数据视图的尾部视图_tableView.tableFooterView = nil;[self.view addSubview:_tableView];//初始化数据源数组_arrayData = [[NSMutableArray alloc] init];for (int i = 1; i < 20; i++) {NSString *str = [NSString stringWithFormat:@"A %d",i];[_arrayData addObject:str];}//当数据的数据源发生变化时,//更新数据视图,重新加载数据[_tableView reloadData];[self createBtn];
}-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{return _arrayData.count;
}//默认情况下
-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView
{return 1;
}-(UITableViewCell*) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{NSString *strID = @"ID";//尝试获取可以复用的单元格//如歌得不到,返回nilUITableViewCell *cell = [_tableView dequeueReusableCellWithIdentifier:strID];//需要显示子标题必须为UITableViewCellStyleSubtitleif (cell == nil) {cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:strID];}//单元格文字赋值cell.textLabel.text = [_arrayData objectAtIndex:indexPath.row];cell.detailTextLabel.text = @"儿子标题";NSString *str = [NSString stringWithFormat:@"%d.jpg",(indexPath.row % 10 + 1)];UIImage *image = [UIImage imageNamed:str];UIImageView *iView = [[UIImageView alloc] initWithImage:image];cell.imageView.image = image;// UIImageView *iView = [[UIImageView alloc] initWithImage:image]//设置默认的图标信息return cell;}-(void) createBtn
{isEdit = NO;btnEdit = [[UIBarButtonItem alloc] initWithTitle:@"编辑" style:UIBarButtonItemStylePlain target:self action:@selector(pressEdit)];btnFinish = [[UIBarButtonItem alloc] initWithTitle:@"完成" style:UIBarButtonItemStylePlain target:self action:@selector(pressFinish)];btnDelete = [[UIBarButtonItem alloc] initWithTitle:@"删除" style:UIBarButtonItemStylePlain target:self action:@selector(pressDelete)];self.navigationItem.rightBarButtonItem = btnEdit;}-(void) pressEdit
{isEdit = YES;self.navigationItem.rightBarButtonItem = btnFinish;[_tableView setEditing:YES];self.navigationItem.leftBarButtonItem = btnDelete;}-(void) pressFinish
{isEdit = NO;self.navigationItem.rightBarButtonItem = btnEdit;[_tableView setEditing:NO];self.navigationItem.leftBarButtonItem = nil;}- (void)pressDelete {// 获取被选中的行的索引集合NSArray *selectedRows = [_tableView indexPathsForSelectedRows];if (selectedRows.count > 0) {// 创建一个可变数组,用于存储需要删除的数据NSMutableArray *rowsToDelete = [NSMutableArray array];for (NSIndexPath *indexPath in selectedRows) {// 获取需要删除的数据的索引NSInteger row = indexPath.row;// 添加到需要删除的数据数组中[rowsToDelete addObject:[NSNumber numberWithInteger:row]];}// 排序需要删除的数据的索引,以确保正确删除NSArray *sortedRows = [rowsToDelete sortedArrayUsingSelector:@selector(compare:)];// 逆序遍历需要删除的数据的索引,从数据源数组中删除对应的数据for (NSInteger i = sortedRows.count - 1; i >= 0; i--) {NSInteger deleteRow = [sortedRows[i] integerValue];[_arrayData removeObjectAtIndex:deleteRow];}// 删除对应的行[_tableView deleteRowsAtIndexPaths:selectedRows withRowAnimation:UITableViewRowAnimationAutomatic];}
}
//单元格显示效果协议
- (UITableViewCellEditingStyle) tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{//默认为删除//UITableViewCellEditingStyleDelete:删除//UITableViewCellEditingStyleInsert:插入//UITableViewCellEditingStyleNone:空//多选状态UITableViewCellEditingStyleDelete|UITableViewCellEditingStyleInsertreturn UITableViewCellEditingStyleDelete|UITableViewCellEditingStyleInsert;
}//可以显示编辑状态,当手指在单元格上移动时。
- (void) tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{//删除数据源对应的数据[_arrayData removeObjectAtIndex:indexPath.row];//数据源更新[_tableView reloadData];NSLog(@"delete!");
}//选中时调用
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{NSLog(@"选中单元格! %ld, %ld",(long)indexPath.section, (long)indexPath.row);
}//取消时调用
-(void) tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{NSLog(@"取消选中单元格! %ld, %ld",(long)indexPath.section, (long)indexPath.row);
}
@end

我们通过加入一个布尔变量isEdit来判断是否处于编辑状态。在编辑状态下,我们可以对单元格进行插入,删除等操作。
通过使用UITableViewCellEditingStyleDelete|UITableViewCellEditingStyleInsert多选状态,我们可以实现批量删除的操作。
多选后,我们需要重新写编辑状态的删除按钮。即:

- (void)pressDelete {// 获取被选中的行的索引集合NSArray *selectedRows = [_tableView indexPathsForSelectedRows];if (selectedRows.count > 0) {// 创建一个可变数组,用于存储需要删除的数据NSMutableArray *rowsToDelete = [NSMutableArray array];for (NSIndexPath *indexPath in selectedRows) {// 获取需要删除的数据的索引NSInteger row = indexPath.row;// 添加到需要删除的数据数组中[rowsToDelete addObject:[NSNumber numberWithInteger:row]];}// 排序需要删除的数据的索引,以确保正确删除NSArray *sortedRows = [rowsToDelete sortedArrayUsingSelector:@selector(compare:)];// 逆序遍历需要删除的数据的索引,从数据源数组中删除对应的数据for (NSInteger i = sortedRows.count - 1; i >= 0; i--) {NSInteger deleteRow = [sortedRows[i] integerValue];[_arrayData removeObjectAtIndex:deleteRow];}// 删除对应的行[_tableView deleteRowsAtIndexPaths:selectedRows withRowAnimation:UITableViewRowAnimationAutomatic];}
}

效果:
在这里插入图片描述


总结

以上就是对UITableView粗略的学习,还有许多未知的领域等待探索。
下一步,自定义cell和cell的复用!在学习中不断有进步。

这篇关于Ui学习--UITableView的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1067009

相关文章

Java进阶学习之如何开启远程调式

《Java进阶学习之如何开启远程调式》Java开发中的远程调试是一项至关重要的技能,特别是在处理生产环境的问题或者协作开发时,:本文主要介绍Java进阶学习之如何开启远程调式的相关资料,需要的朋友... 目录概述Java远程调试的开启与底层原理开启Java远程调试底层原理JVM参数总结&nbsMbKKXJx

Java深度学习库DJL实现Python的NumPy方式

《Java深度学习库DJL实现Python的NumPy方式》本文介绍了DJL库的背景和基本功能,包括NDArray的创建、数学运算、数据获取和设置等,同时,还展示了如何使用NDArray进行数据预处理... 目录1 NDArray 的背景介绍1.1 架构2 JavaDJL使用2.1 安装DJL2.2 基本操

Vue项目中Element UI组件未注册的问题原因及解决方法

《Vue项目中ElementUI组件未注册的问题原因及解决方法》在Vue项目中使用ElementUI组件库时,开发者可能会遇到一些常见问题,例如组件未正确注册导致的警告或错误,本文将详细探讨这些问题... 目录引言一、问题背景1.1 错误信息分析1.2 问题原因二、解决方法2.1 全局引入 Element

Python中的可视化设计与UI界面实现

《Python中的可视化设计与UI界面实现》本文介绍了如何使用Python创建用户界面(UI),包括使用Tkinter、PyQt、Kivy等库进行基本窗口、动态图表和动画效果的实现,通过示例代码,展示... 目录从像素到界面:python带你玩转UI设计示例:使用Tkinter创建一个简单的窗口绘图魔法:用

element-ui下拉输入框+resetFields无法回显的问题解决

《element-ui下拉输入框+resetFields无法回显的问题解决》本文主要介绍了在使用ElementUI的下拉输入框时,点击重置按钮后输入框无法回显数据的问题,具有一定的参考价值,感兴趣的... 目录描述原因问题重现解决方案方法一方法二总结描述第一次进入页面,不做任何操作,点击重置按钮,再进行下

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]