【iOS】UI学习——UITableView

news2025/4/13 18:23:39

UI学习(四)

  • UITableView基础
  • UITableView协议
  • UITableView高级协议和单元格

UITableView基础

dateSource:数据代理对象
delegate:普通代理对象
numberOfSectionInTableView:获得组数协议
numberOfRowsInSection:获得行数协议
cellForRowAtIndexPath:创建单元格协议

UIViewController.h

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController
<
//实现数据视图的普通协议
//数据视图的普通事件处理
UITableViewDelegate,
//实现数据视图的数据代理协议
//处理数据视图的数据代理
UITableViewDataSource
>
{
    //定义一个数据视图对象
    //数据视图用来显示大量相同的格式的大量信息的视图
    UITableView* _tableView;
}
@end

ViewController.m

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //创建数据视图
    //P1:数据视图的位置
    //P2:数据视图的风格
    //UITableViewStylePlain:普通风格
    //UITableViewStyleGrouped:分组风格
    _tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStyleGrouped];
    //设置数据视图的代理对象
    _tableView.delegate = self;
    //设置数据视图的数据源对象
    _tableView.dataSource = self;
    
    [self.view addSubview: _tableView];
    
}

//获取每组元素的个数(行数)
//程序在显示数据视图时会调用此函数
//返回值:表示每组元素的个数
//P1:数据视图对象本身 P2:那一组需要的行数
-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 5;
}
//设置数据视图的组数
-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView
{
    return 3;
}

//创建单元格对象函数,传入两个参数
//P1:传入这个函数的对象 P2:单元格的索引
-(UITableViewCell*) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString* cellStr = @"cell";
    
    UITableViewCell* cell = [_tableView dequeueReusableCellWithIdentifier:cellStr];
    if(cell == nil) {
        //创建一个单元格对象,传入两个参数
        //P1:单元格的样式 P2:单元格的副用标记
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellStr];
        
    }
    //indexPath.section表示组数
    //indexPath.row表示行数
    NSString* str = [NSString stringWithFormat:@"第%ld组,第%ld行!", indexPath.section, indexPath.row];
    //将单元格的主文字内容赋值
    cell.textLabel.text = str;
    return cell;
}

@end

UITableView协议

heightForRowAtIndexPath:获取单元格高度协议
heightForHeaderInSection:数据视图头部高度协议
heightForFooterInSection:数据视图尾部高度协议
titleForFooterINSection:数据视图尾部的标题协议
titleForHeaderInSection:数据视图头部标题协议

UIViewController.h

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController
<UITableViewDataSource,UITableViewDelegate>
{
    //定义数据视图对象
    UITableView* _tableview;
    //声明一个数据源
    NSMutableArray* _arrayData;
}


@end

UIViewController.m

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    _tableview = [[UITableView alloc] initWithFrame:CGRectMake(0, 20, 480, 832) 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 20;
}

@end

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

UITableView高级协议和单元格

高级协议的几个函数
commitEditingStyle:提交编辑函数
canEditRowAtIndexPath:开启关闭编辑单元格
editingStyleForRowAtIndexPath:编辑单元格风格设定
didSelectRowAtIndexPath:选中单元格响应协议
didDeselectRowAtIndexPath:反选单元格响应协议
单元格几个函数
dequeueReusableCellWithIdentifier:获取可以复用的单元格对象
initWithStyle:根据风格创建单元格对象
reuseldentifier:设置可以复用单元格的ID

设置一个导航控制器

#import "SceneDelegate.h"
#import "ViewController.h"
@interface SceneDelegate ()

@end

@implementation SceneDelegate


- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
    
    self.window.frame = [UIScreen mainScreen].bounds;
    
    UINavigationController* nav = [[UINavigationController alloc] initWithRootViewController:[[ViewController alloc] init]];
    
    self.window.rootViewController = nav;
}


- (void)sceneDidDisconnect:(UIScene *)scene {
    // Called as the scene is being released by the system.
    // This occurs shortly after the scene enters the background, or when its session is discarded.
    // Release any resources associated with this scene that can be re-created the next time the scene connects.
    // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead).
}


- (void)sceneDidBecomeActive:(UIScene *)scene {
    // Called when the scene has moved from an inactive state to an active state.
    // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
}


- (void)sceneWillResignActive:(UIScene *)scene {
    // Called when the scene will move from an active state to an inactive state.
    // This may occur due to temporary interruptions (ex. an incoming phone call).
}


- (void)sceneWillEnterForeground:(UIScene *)scene {
    // Called as the scene transitions from the background to the foreground.
    // Use this method to undo the changes made on entering the background.
}


- (void)sceneDidEnterBackground:(UIScene *)scene {
    // Called as the scene transitions from the foreground to the background.
    // Use this method to save data, release shared resources, and store enough scene-specific state information
    // to restore the scene back to its current state.
}


@end

ViewController.h:

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController<UITableViewDelegate,UITableViewDataSource>
{
    //数据视图
    UITableView* _tableview;
    //数据源
    NSMutableArray* _arrayData;
    
    UIBarButtonItem* _btnEdit;
    UIBarButtonItem* _btnFinish;
    UIBarButtonItem* _btnDelete;
    
    BOOL _isEdit;
}


@end

ViewController.m:

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    _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 = 0; i < 20; i++)
    {
        NSString* str = [NSString stringWithFormat:@"A %d", i];
        
        [_arrayData addObject:str];
    }
    
    //当数据的数据源发生变化时
    //更新数据视图,重新加载数据
    [_tableview reloadData];
    [self createBtn];
}

-(void) createBtn
{
    _isEdit = NO;
    //设置导航栏按钮
    _btnEdit = [[UIBarButtonItem alloc] initWithTitle:@"编译" style:UIBarButtonItemStyleDone target:self action:@selector(pressEdit)];
    _btnDelete = [[UIBarButtonItem alloc] initWithTitle:@"删除" style:UIBarButtonItemStyleDone target:self action:nil];
    _btnFinish = [[UIBarButtonItem alloc] initWithTitle:@"完成" style:UIBarButtonItemStyleDone target:self action:@selector(pressFinish)];
    
    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;
}

-(NSInteger) tableView:(UITableView*) tableView numberOfRowsInSection:(NSInteger)section
{
    return _arrayData.count;
}

//默认组数返回1
-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

-(UITableViewCell*) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString* strID = @"ID";
    //尝试获取可以复用的单元格
    //如果得不到,返回nil
    UITableViewCell* cell = [_tableview dequeueReusableCellWithIdentifier:strID];
    if(cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:strID];
    }
    //单元格文字赋值
    cell.textLabel.text = [_arrayData objectAtIndex:indexPath.row];
    //设置文字子标题
    cell.detailTextLabel.text = @"子标题";
    //为单元格添加图片,设置图标
    NSString* str = [NSString stringWithFormat:@"%d.png", 12];
    
    UIImage* image = [UIImage imageNamed:str];
    
    UIImageView* iView = [[UIImageView alloc] initWithImage:image];
    cell.imageView.image = image;
    
    return cell;
}

-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //默认为删除
    //UITableViewCellEditingStyleInsert 增加
    //UITableViewCellEditingStyleDone 空
    return UITableViewCellEditingStyleDelete;
}
//可以显示编辑状态,当手指在单元格上移动时
-(void) tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    //删除数据源对应的数据
    [_arrayData removeObjectAtIndex:indexPath.item];
    //数据源更新
    [_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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1791677.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

引擎:Shader

一、原理 创建Shader脚本&#xff0c;创建材质球&#xff0c;将物体的渲染效果Shader脚本挂载到材质球&#xff0c;最后把材质球挂到3d物体上面从而实现渲染。 二、模型边缘发光 原理&#xff1a;正对着摄像机的模型三角面边缘光最弱&#xff0c;垂直于摄像机的模型三角面边缘光…

算法金 | 10 大必知的自动化机器学习库(Python)

大侠幸会&#xff0c;在下全网同名[算法金] 0 基础转 AI 上岸&#xff0c;多个算法赛 Top [日更万日&#xff0c;让更多人享受智能乐趣] 一、入门级自动化机器学习库 1.1 Auto-Sklearn 简介&#xff1a; Auto-Sklearn 是一个自动机器学习库&#xff0c;基于 Python 的 scikit…

python自动获取网站关闭清单脚本

1.网站关闭清单 2.网站关闭脚本 02nginx_close.sh #!/bin/bash#echo "13 test.com" #ssh root192.168.120.145 "/data/shells/02nginx_close.sh > /dev/null 2>&1 &"#echo "14 test1.com" #ssh root192.168.179.5 "/data/s…

【python】 ModuleNotFoundError: No module named datasets

成功解决“ModuleNotFoundError: No module named datasets”错误的全面指南 在Python编程中&#xff0c;遇到ModuleNotFoundError: No module named datasets这样的错误通常意味着Python解释器无法找到名为datasets的模块。datasets是一个流行的Python库&#xff0c;常用于加载…

通信技术振幅键控(ASK)调制与解调硬件实验

一、实验目的 1. 掌握用键控法产生ASK信号的方法&#xff1b; 2. 掌握ASK非相干解调的原理。 二、实验内容 1. 观察ASK已调信号的波形&#xff1b; 2. 观察ASK解调信号的波形。 三、实验器材 1. 双踪示波器&#xff1b; 2. 通信原理实验箱信号源模块、③、④、⑦号模块。…

JVM之【字节码/Class文件/ClassFile 内容解析】

说在前面的话 Java语言:跨平台的语言(write once,run anywhere) 当Java源代码成功编译成字节码后&#xff0c;如果想在不同的平台上面运行&#xff0c;则无须再次编译这个优势不再那么吸引人了。Python、PHP、Perl、Ruby、Lisp等有强大的解释器。跨平台似乎已经快成为一门语言…

面试官:如何实现大文件切片上传?

公众号&#xff1a;程序员白特&#xff0c;关注我&#xff0c;每天进步一点点~ 前端上传文件很大时,会出现各种问题,比如连接超时了,网断了,都会导致上传失败,这个时候就需要将文件切片上传,下面我们就来学习一下如何使用vue实现大文件切片上传吧 大文件为什么要切片上传 前端…

跨域请求解决方法----不允许有多个 ‘Access-Control-Allow-Origin‘ CORS 头

后端配置了代码&#xff1a; spring:application:name: spzx-server-gatewaycloud:nacos:discovery:server-addr: localhost:8848gateway:discovery:locator:enabled: trueglobalcors:cors-configurations:[/**]:allowedOriginPatterns: "*"# 允许请求中携带的头信息…

word 无法自动检测拼写

word 有时候不能分辨是哪种语言,比如把英语错认为法语 。 例如&#xff1a;Interlaayer spacace,发现误认为是法语。 1、选中Interlaayer spacace 2、点击语言下拉按钮 选择设置校对语言 发现校对语言为法语 3、手动修改校对语言为英语&#xff0c;并点击确认。 4、发现现…

负压实验室设计建设方案

随着全球公共卫生事件的频发&#xff0c;负压实验室的设计和建设在医疗机构中的重要性日益凸显。负压实验室&#xff0c;特别是负压隔离病房&#xff0c;主要用于控制传染性疾病的扩散&#xff0c;保护医护人员和周围环境的安全。广州实验室装修公司中壹联凭借丰富的实验室装修…

RN:Error: /xxx/android/gradlew exited with non-zero code: 1

问题 执行 yarn android 报错&#xff1a; 解决 这个大概率是缓存问题&#xff0c;我说一下我的解决思路 1、yarn doctor 2、根据黄色字体提示&#xff0c;说我包版本不对&#xff08;但是这个是警告应该没事&#xff0c;但是我还是装了&#xff09; npx expo install --…

IO流,文件操作

参考 Java IO 基础知识总结 | JavaGuide 史上最骚最全最详细的IO流教程&#xff0c;没有之一&#xff01; - 宜春 - 博客园 零、io-流简介 IO 即 Input/Output&#xff0c;输入和输出。数据输入到计算机内存的过程即输入&#xff0c;反之输出到外部存储&#xff08;比如数据…

使用OpenPCDet实现VoxelNext进行训练和测试:实现NuScence数据集的全局感知结果可视化

在自动驾驶和机器人技术日益蓬勃发展的今天&#xff0c;3D目标检测技术成为关键的一环&#xff0c;它赋予机器以理解和响应周围环境的能力。本文将深入探讨如何使用开源的OpenPCDet框架训练先进的VoxelNeX模型&#xff0c;并在nuScenes数据集上进行训练、测试&#xff0c;最后实…

grpc接口调用

grpc接口调用 准备依赖包clientserver 参考博客&#xff1a; Grpc项目集成到java方式调用实践 gRpc入门和springboot整合 java 中使用grpc java调用grpc服务 准备 因为需要生成代码&#xff0c;所以必备插件 安装后重启 依赖包 <?xml version"1.0" encoding&…

计算机三级等级考试

计算机等级考试&#xff1a; 一&#xff1a;理论知识考试 100分考60分 1&#xff1a;题库 二&#xff1a;技能考试 100分考60分 1&#xff1a;写文档 项目概述 功能描述 数据库设计 UML 绘 图 用例图 与 包图&#xff08;两个图&#xff09; 2&…

MYSQL一、MYSQL的了解

一、MySQL概述 1、数据库相关概念 为了方便&#xff0c;我们一般把mysql数据库管理系统简称位mysql数据库 通过可以操作数据库管理系统&#xff0c;然后再通过数据库管理系统操作&#xff08;数据库&#xff09;和&#xff08;数据库里面的数据&#xff09; 2、当前主流的关系…

Etcd Raft架构设计和源码剖析1:宏观架构

Etcd Raft架构设计和源码剖析1&#xff1a;宏观架构 | Go语言充电站 序言 Etcd提供了一个样例contrib/raftexample&#xff0c;用来展示如何使用etcd raft。这篇文章通过raftexample介绍如何使用etcd raft。 raft服务 raftexample是一个分布式KV数据库&#xff0c;客户端可…

linux mtd分区应用操作sample之某分区擦除

什么是擦除? 把flash相关的区域数据bit置为1的过程 #include <mtd/mtd-user.h> #include <mtd/mtd-abi.h> struct erase_info_user {__u32 start; // 起点 __u32 length; //长度 块大小对齐 不然报参数失败 };struct erase_info_user64 {__u64 sta…

Android约束布局ConstraintLayout的使用

Android引入约束布局的目的是为了减少布局层级的嵌套&#xff0c;从而提升渲染性能。约束布局综合线性布局、相对布局、帧布局的部分功能&#xff0c;缺点也很明显&#xff0c;就是可能要多写几行代码。所以约束布局使用时&#xff0c;还得综合考虑代码量。提升性能也并不一定非…

postman教程-15-前置脚本

上一小节我们学习了Postman生成随机数的方法&#xff0c;本小节我们讲解一下Postman前置脚本的使用方法。 Postman中的前置脚本&#xff08;Pre-request Script&#xff09;允许你在发送请求之前运行JavaScript代码。这可以用于修改请求头、查询参数、请求体等&#xff0c;或者…