当前位置: 首页 > news >正文

UI学习(三)

UI学习(三)

  • 多界面传值
  • UITableView
    • UITableView基础
    • UITableView协议
    • UITableView高级协议与单元格

多界面传值

多界面传值是在不同视图控制器之间传递数据的过程。主要实现方法为定义一个代理(delegate)对象,通过代理对象实现协议函数使原来访问不到第一个对象的第二个对象可以访问第一个对象。

代码实现:

定义两个视图控制器,在第二个视图控制器中定义视图控制器一为代理对象来实现代理协议,使在视图控制器二中可以改变视图控制一的颜色,再让视图控制器一遵守视图控制器二中的代理协议,并在实现方法部分实现该代理协议。

视图控制器二:

//SecondViewController.h
#import <UIKit/UIKit.h>NS_ASSUME_NONNULL_BEGIN
//定义视图控制器二的代理协议
@protocol SecondDelegate <NSObject>-(void)changeColor:(UIColor*)color;@end
@interface SecondViewController : UIViewController
@property(assign, nonatomic) NSInteger tag;
//定义代理属性执行代理函数
//代理对象一定要实现协议
@property(nonatomic, weak) id<SecondDelegate> delegate;
@end
//SecondViewController.m
#import "SecondViewController.h"@interface SecondViewController ()@end@implementation SecondViewController- (void)viewDidLoad {[super viewDidLoad];self.view.backgroundColor = [UIColor redColor];UIBarButtonItem *btnChange = [[UIBarButtonItem alloc] initWithTitle:@"改变颜色" style:UIBarButtonItemStyleDone target:self action:@selector(pressBtn)];self.navigationItem.rightBarButtonItem = btnChange;
}
-(void)pressBtn {[_delegate changeColor:[UIColor blueColor]];
}

视图控制器一:

//FirstViewController.h
//申明要遵守的协议
#import <UIKit/UIKit.h>
#import "SecondViewController.h"
@interface FirstViewController : UIViewController<SecondDelegate>
@end
//FirstViewController.m
#import "FirstViewController.h"
@interface FirstViewController ()@end@implementation FirstViewController- (void)viewDidLoad {[super viewDidLoad];self.title = @"根视图";self.view.backgroundColor = [UIColor yellowColor];self.navigationController.navigationBar.translucent = NO;UINavigationBarAppearance *app = [[UINavigationBarAppearance alloc] init];app.backgroundColor = [UIColor greenColor];app.shadowImage = [[UIImage alloc] init];app.shadowColor = nil;self.navigationController.navigationBar.standardAppearance = app;self.navigationController.navigationBar.scrollEdgeAppearance = app;
}
//点击视图空白处时推出视图控制器二
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {SecondViewController *vc2 = [[SecondViewController alloc] init];vc2.view.backgroundColor = [UIColor grayColor];//将当前控制器作为代理对象vc2.delegate = self;[self.navigationController pushViewController:vc2 animated:YES];
}
-(void)changeColor:(UIColor *)color {self.view.backgroundColor = color;
}

运行结果:

在这里插入图片描述

UITableView

UITableView基础

UITableView是指数据视图,如表格。

在创建UITableView时,必须实现协议中的几个函数:

  • 获取组数:numberOfSectionsInTableView
  • 获取每组元素个数:tableView
  • 创建单元格:cellForRowAtIndexPath
  • 创建单元格对象函数:numberOfSectionsInTableView
  • 设置数据代理对象:dataSource:
  • 设置普通代理对象:delegate
  • 获取行数:numberOfRowsInSection

演示一下代码:

//ViewController.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];//创建数据视图//参数1:数据视图的位置//参数2:数据视图的风格_tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStyleGrouped];//分组风格_tableView.delegate = self;//代理对象_tableView.dataSource = self;//代理源对象[self.view addSubview:_tableView];
}//获取每组元素个数(行数)
//参数1:数据视图对象
//参数2:需要的行数
- (NSInteger)tableView:(nonnull UITableView *)tableView numberOfRowsInSection:(NSInteger)section {return 5;
}//设置数据视图组数
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {return 3;
}//创建单元格对象函数
//参数1:函数的对象
//参数2:单元格索引(即行数组数)
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {NSString *cellStr = @"cell";UITableViewCell *cell = [_tableView 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

运行效果:

在这里插入图片描述

其中,区分一下delegate 和 dataSource:

属性协议主要职责
delegateUITableViewDelegate处理视图交互和外观 (点击、滚动、行高、单元格显示/隐藏等)
dataSourceUITableViewDataSource提供数据内容和结构 (行数、单元格内容、编辑操作等)

dataSource的两个方法(返回行数和单元格)必须实现,delegate的方法可以选择性实现。通俗的说,对于一个餐厅,dataSource可以类比为准备食物的厨师,delegate可以类比为处理顾客需求的服务员。

UITableView协议

如果我们想修改这个单元格的样式,我们可以通过以下相应的函数:

  • 获取单元格高度:heightForRowAtIndexPath
  • 获取数据视图头部高度:heightForHeaderInSection
  • 获取数据视图尾部高度:heightForFooterInSection
  • 获取数据视图尾部标题:titleForFooterInSection
  • 获取数据视图头部标题:titleForHeaderInSection

演示下代码:

//ViewController.h
#import <UIKit/UIKit.h>@interface ViewController : UIViewController <UITableViewDelegate, UITableViewDataSource> {UITableView *_tableView;NSMutableArray *_arrayData;//数据源
}@end
//ViewController.m
#import "ViewController.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];_tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 40, 394, 825) 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:(nonnull UITableView *)tableView numberOfRowsInSection:(NSInteger)section {NSInteger numRow = [[_arrayData objectAtIndex:section] count];//获取一维数组的个数,即每组元素个数return numRow;
}//获取单元格
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {//定义一个重用标识符NSString *str = @"cell";//创建一个类型为'cell'的UITableViewCell//dequeueReusableCellWithIdentifier:在重用队列里查找是否有可复用的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

代码实现:

#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;
}
@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 = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;_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];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {return _arrayData.count;
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {return 1;//默认组数为1
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {NSString *strID = @"ID";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:@"/Users/mac/Desktop/%ld.jpg", (long)(indexPath.row % 8 + 1)];//余数循环,使图片重复使用UIImage *image = [UIImage imageNamed:str];cell.imageView.image = image;[self createBtn];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 {}
//单元格显示效果协议
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {return UITableViewCellEditingStyleDelete;//默认为删除状态//return UITableViewCellEditingStyleDelete| UITableViewCellEditingStyleInsert;
}
//通过手指滑动实现删除按钮功能
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {[_arrayData removeObjectAtIndex:indexPath.row];[_tableView reloadData];//更新NSLog(@"删除");
}
//选中单元格时执行
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {NSLog(@"选中单元格!%lu, %lu", indexPath.section, indexPath.row);
}
//在已经选择单元格的情况下,再选择另一个单元格时取消上一个单元格
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath {NSLog(@"取消选中单元格!%lu, %lu", indexPath.section, indexPath.row);
}
@end

运行结果:

在这里插入图片描述

在这里插入图片描述

http://www.xdnf.cn/news/956449.html

相关文章:

  • 嵌入式学习Day34
  • VS Code中Augment AI免费额度用尽的完美解决方案
  • CppCon 2015 学习:The Birth of Study Group 14
  • Android15默认开启无障碍服务
  • ui框架-文件上传组件
  • 高密度ARM服务器的散热设计
  • JAVA开发工具箱
  • Easy Excel
  • Shell脚本 - 查看系统信息
  • 设计模式作业
  • Unity中的Time.fixedDeltaTime
  • 9. 线性表的顺序表示和实现(1)
  • TCP和UDP区别
  • 关于 WASM:1. WASM 基础原理
  • linux 下常用变更-8
  • VisualXML全新升级 | 新增数据库编辑功能
  • 怎么让Comfyui导出的图像不包含工作流信息,
  • 三网智能切换技术如何造富?拆解格行WiFi代理的管道收益模型
  • 直播APP平台中如何实现人脸美颜功能?美颜SDK技术详解
  • React第五十七节 Router中RouterProvider使用详解及注意事项
  • Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)
  • PLC入门【4】基本指令2(SET RST)
  • 分布式系统简述
  • Appium下载安装配置保姆教程(图文详解)
  • 基于 Three.js 的数字雨波纹效果技术解析
  • 浏览器工作原理11 [#] this:从JavaScript执行上下文视角讲this
  • SpringBoot请求限流(RateLimiter)
  • 针对药品仓库的效期管理问题,如何利用WMS系统“破局”
  • align-items: start和align-items: flex-start的区别
  • 技术创新赋能产业升级:国际数字影像产业园引领变革浪潮