UITableView基础使用
View.m中
// 都是一样的cell, 只有一个分组
self.tableView = [[UITableView alloc]initWithFrame:self.frame style:UITableViewStylePlain];
// 带分组的tableView
self.tableView = [[UITableView alloc]initWithFrame:self.frame style:UITableViewStyleGrouped];
// 1. 设置行高
self.tableView.rowHeight = 100;
// 2. 设置分割线的颜色和样式
self.tableView.separatorColor = [UIColor magentaColor];
// tableView 上面展示的每一条数据都是放在 一个cell上面
self.tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
Controller.m中
// 以后养成习惯(直接把两个方法直接都写上)
@interface RootViewController ()<UITableViewDataSource,UITableViewDelegate>
// 直接设置两个代理
self.rootV.tableView.dataSource = self;
self.rootV.tableView.delegate = self;
// 设置tableView (Section)分组数
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 4;
}
// 设置tableView (row)每个分组的行数
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
int a = 0;
switch (section) {
case 0:
a = 1;
break;
case 1:
a = 3;
break;
case 2:
a = 1;
break;
case 3:
a = 1;
break;
default:
break;
}
return a;
}
3. 设置每条cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
// cell的reuseldentifier是重用机制的关键
// 1. 声明一个重用标识符(唯一)
static NSString *cell_id = @"cell";
// 2. 去重用池寻找有次标识符的cell
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cell_id];
// 3. 判断
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cell_id];
}
// 注意:重用池是由一个NSMutableSet实现的 iOS为了保证内存的合理使用,提供了重用机制,划出屏幕的 cell 被放到重用池中,加上了一个重用标识符,如果下次使用,直接使用带标识符的cell即可
cell.textLabel.text = @"张三";
cell.detailTextLabel.text = @"张三简介";
return cell;
}
// 设置分区头部的标题
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
return [NSString stringWithFormat:@"联系人"];
}
// 设置尾部标题
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section{
return @"结束";
}
// 显示右侧竖排索引
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView{
NSArray *arr = @[@"0",@"1",@"2",@"3"];
return arr;
}
#pragma mark UITableViewDelegate
// 返回header 的高度
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
return 50;
}
// 返回hearder的view
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
UIView *temp = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 50, 50)];
//temp.backgroundColor = [UIColor grayColor];
return temp;
}
// 返回footer的高度
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{
return 50;
}
// 返回footer的view
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section{
UIView *temp = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 50, 50)];
temp.backgroundColor = [UIColor blackColor];
return temp;
}
// 行高
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
if (indexPath.section == 2 && indexPath.row == 2) {
return 30;
}else
return 100;
}
// 选中某一行(千万别写错方法)
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
// if (indexPath.row == 1 && indexPath.section == 2) {
// NSLog(@"aaaaaaaa");
// }
NextViewController *nextVC = [[NextViewController alloc]init];
//[self.navigationController pushViewController:nextVC animated:YES];
// 模态实现
[self.navigationController presentViewController:nextVC animated:YES completion:^{
}];
}
Cell增删 移动
#import"RootViewController.h"
#import "RootView.h"
@interface RootViewController ()<UITableViewDataSource,UITableViewDelegate>
@property(nonatomic,retain)RootView *rootV;
@property(nonatomic,retain)NSMutableArray *allArr;
@property(nonatomic,assign)UITableViewCellEditingStyle editStyle;
@end
@implementation RootViewController
- (void)loadView{
self.rootV = [[RootView alloc]initWithFrame:[[UIScreen mainScreen]bounds]];
self.view = self.rootV;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self p_date];
self.rootV.tableView.delegate = self;
self.rootV.tableView.dataSource = self;
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc]initWithTitle:@"添加" style:UIBarButtonItemStylePlain target:self action:@selector(leftAction:)];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]initWithTitle:@"删除" style:UIBarButtonItemStylePlain target:self action:@selector(rightAction:)];
}
设置分组数 (section)
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return self.allArr.count;
}
设置每个分组的行数 (row)
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [self.allArr[section] count];
}
设值每个Cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *cell_id = @"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cell_id];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cell_id];
}
cell.backgroundColor = [UIColor colorWithRed:arc4random()%256/255.0 green:arc4random()%256/255.0 blue:arc4random()%256/255.0 alpha:1];
cell.textLabel.text = self.allArr[indexPath.section][indexPath.row];
return cell;
}
数据处理
- (void)p_date{
self.allArr = [NSMutableArray array];
NSMutableArray * arr1 = @[@"孙行者",@"者行孙",@"行者孙"].mutableCopy;
NSMutableArray *arr2 = @[@"大师兄,师傅被妖怪抓走了",@"大师兄,二师兄被妖怪抓走了",@"大师兄,白龙马被妖怪抓走了",@"大师兄,我被妖怪抓走了"].mutableCopy;
[self.allArr addObject:arr1];
[self.allArr addObject:arr2];
}
增删
// 1. 处于编辑状态
- (void)rightAction:(UIBarButtonItem *)sender{
_editStyle = UITableViewCellEditingStyleDelete;
[self.rootV.tableView setEditing:!self.rootV.tableView.editing animated:YES];
}
- (void)leftAction:(UIBarButtonItem *)sender{
_editStyle = UITableViewCellEditingStyleInsert;
[self.rootV.tableView setEditing:!self.rootV.tableView.editing animated:YES];
}
//2. 指定哪一行可以被编辑
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath{
return YES;
}
// 3. 设置编辑样式
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath{
return self.editStyle;
}
// 4. 完成编辑(1. 修改数据源 2. 修改UI)
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
if (self.editStyle == UITableViewCellEditingStyleInsert) {
// 1.修改数据源
[self.allArr[indexPath.section] insertObject:@"aaa" atIndex:indexPath.row + 1];
// 2. 修改UI
NSIndexPath *temp = [NSIndexPath indexPathForRow:indexPath.row + 1 inSection:indexPath.section];
[self.rootV.tableView insertRowsAtIndexPaths:@[temp] withRowAnimation:UITableViewRowAnimationLeft];
}else{
[self.allArr[indexPath.section] removeObjectAtIndex:indexPath.row];
[self.rootV.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationLeft];
}
}
移动
// 1. 设置处于编辑状态
// 2. 指定哪一行可以被移动
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath{
return YES;
}
// 3. 完成移动
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath{
if (sourceIndexPath.section == destinationIndexPath.section) {
[self.allArr[sourceIndexPath.section] exchangeObjectAtIndex:sourceIndexPath.row withObjectAtIndex:destinationIndexPath.row];
}else{
[self.allArr[destinationIndexPath.section] insertObject:self.allArr[sourceIndexPath.section][sourceIndexPath.row] atIndex:destinationIndexPath.row];
[self.allArr[sourceIndexPath.section] removeObjectAtIndex:sourceIndexPath.row];
}
// // 1. 拿出数据
// NSString *temp = self.allArr[sourceIndexPath.section][sourceIndexPath.row];
// // 从数组中删除
// [self.allArr[sourceIndexPath.section] removeObjectAtIndex:sourceIndexPath.row];
// // 插入到新的位置
// [self.allArr[destinationIndexPath.section] insertObject:temp atIndex:destinationIndexPath.row];
// iOS tableViewCell 不建议跨区移动,,必须想办法限制
}
// 设置禁止跨分组移动
//- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
//{
// if (sourceIndexPath.section == proposedDestinationIndexPath.section) {
// return proposedDestinationIndexPath;
// }else{
// return sourceIndexPath;
// }
//}
UITableViewController注意事项
// 1. 先注册
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"cell"];
// 2. 修改identifier(标识符) 为@"cell"
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
自定义Cell和Model
1. plist文件
NSString *filePath = [[NSBundle mainBundle]pathForResource:@"Property List" ofType:@"plist"];
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:filePath];
2.Cell_Model
// 1. 新建类 继承于 NSObject 专门处理数据
@interface Person : NSObject
// .h写属性 是跟后台的数据对应的(名字必须对应)
@property(nonatomic,retain)NSString *ImageName;
@property(nonatomic,retain)NSString *personName;
@end
#import "Person.h"
@implementation Person
// 2. 为了防止后台数据里的key 跟属性名不一样 必须在.m里面洗这个方法,防止程序崩溃
- (void)setValue:(id)value forUndefinedKey:(NSString *)key{
}
@end
自定义cell 和model的使用
#import <UIKit/UIKit.h>
@class Person;
@interface MyCell : UITableViewCell
@property(nonatomic,retain)UIImageView *myImage;
@property(nonatomic,retain)UILabel *nameLabel;
// 3 . 写方法把获取的数据传给cell
- (void)personValue:(Person *)aPerson;
@end
//************************************自定义Cell************************************
#import "MyCell.h"
#import "Person.h"
@implementation MyCell
-(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
[self p_setupView];
}
return self;
}
- (void)p_setupView{
self.myImage = [[UIImageView alloc]initWithFrame:CGRectMake(10, 10, 60, 60)];
self.myImage.backgroundColor = [UIColor blueColor];
[self.contentView addSubview:self.myImage];
self.nameLabel = [[UILabel alloc]initWithFrame:CGRectMake(CGRectGetMaxX(self.myImage.frame) + 10, CGRectGetMinY(self.myImage.frame),CGRectGetWidth(self.contentView.frame) - CGRectGetWidth(self.myImage.frame) - 30, CGRectGetHeight(self.myImage.frame))];
self.nameLabel.backgroundColor = [UIColor yellowColor];
[self.contentView addSubview:self.nameLabel ];
}
// 当bounds改变的时候结构也跟着改变
- (void)layoutSubviews{
self.nameLabel.frame = CGRectMake(CGRectGetMaxX(self.myImage.frame) + 10,
CGRectGetMinY(self.myImage.frame),
CGRectGetWidth(self.contentView.frame) - CGRectGetWidth(self.myImage.frame) - 30,
CGRectGetHeight(self.myImage.frame));
}
// 传数据给cell
// 4 .(实现)利用传进来的model类,给cell空间的属性进行赋值
- (void)personValue:(Person *)aPerson{
self.myImage.image = [UIImage imageNamed:aPerson.ImageName];
self.nameLabel.text = aPerson.personName;
}
//************************************自定义Cell************************************
#import "RootTableViewController.h"
#import "MyCell.h"
#import "Person.h"
@interface RootTableViewController ()
// 5. 创建一个字典 用来存储dict信息
@property(nonatomic,retain)NSMutableDictionary *personDict;
@property(nonatomic,retain)NSMutableArray *GroupName;
@end
@implementation RootTableViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 1. 注册
[self.tableView registerClass:[MyCell class] forCellReuseIdentifier:@"cell"]
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
[self p_date];
}
- (void)p_date{
// 6. 拿到后台数据
NSString *filePath = [[NSBundle mainBundle]pathForResource:@"Property List" ofType:@"plist"];
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:filePath];
self.GroupName = [NSMutableArray array];
self.personDict = [NSMutableDictionary dictionary];
// 遍历dict字典 获得key
for (NSString *key in dict) {
NSMutableArray *temp = [NSMutableArray array];
// 把遍历出来的key 存到 字典中
[self.personDict setObject:temp forKey:key];
// 把key存到一个数组中
[self.GroupName addObject:key];
//遍历字典存储的数组 获取数组中每个存储个人信息的字典
for (NSDictionary *d in dict[key]) {
Person *p = [[Person alloc]init];
// KVC
// 将存储每个人的字典的键值对, 赋值给person
[p setValuesForKeysWithDictionary:d];
// 将person 存储到字典中
[self.personDict[key] addObject:p];
}
}
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// 7.返回 字典里面的分组数
return self.GroupName.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// 8. 返回字典中每个分组中person的个数
NSArray *temp = [self.personDict objectForKey:self.GroupName[section]];
return temp.count;
//return [[self.personDict objectForKey:self.GroupName[section]] count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MyCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
NSArray *tempArr = [self.personDict objectForKey:self.GroupName[indexPath.section]];
Person *tempPerson = tempArr[indexPath.row];
[cell personValue:tempPerson];
return cell;
}
// 设置行高
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return 80;
}
多种Cell混合使用、懒加载
1. 多种Cell的混合使用
// 创建不同的Cell 根据if条件判断使用哪个Cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
Person *p = self.dateArr[indexPath.row];
if ([p.gender isEqualToString:@"男"]) {
BoyCell *cell1 = [tableView dequeueReusableCellWithIdentifier:@"cell1"];
cell1.boyLabel.text = p.name;
return cell1;
}else{
GirlCell *cell2 = [tableView dequeueReusableCellWithIdentifier:@"cell2"];
cell2.girlImage.image =[ UIImage imageNamed:p.name];
return cell2;
}
}
2. 自定义Cell高度 (懒加载)
// 懒加载 (延迟加载) 有了它以前的自定义初始化就不用写,刚刚相当于重写了属性的getter方法 方法里面只需要做 是否为空的判断即可
- (UILabel *)myLabel{
if (_myLabel == nil) {
self.myLabel = [[UILabel alloc]initWithFrame:CGRectMake(10, 10, CGRectGetWidth(self.contentView.frame) - 20, 60)];
self.myLabel.backgroundColor = [UIColor grayColor];
[self.contentView addSubview:self.myLabel];
}
return _myLabel;// 写 return 和 if 条件 的时候写 _的实例变量
}
#import "RootTableViewController.h"
#import "MyTableViewCell.h"
@interface RootTableViewController ()
@property(nonatomic,retain)NSString *contentStr;
@end
@implementation RootTableViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self.tableView registerClass:[MyTableViewCell class] forCellReuseIdentifier:@"cell"];
// self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
self.contentStr = [NSString stringWithFormat:@"从南边来了个喇嘛,提拉着五斤塔嘛。从北边来个哑吧,腰里别着个喇叭,提拉塔嘛的喇嘛,要拿塔嘛换别喇叭哑巴的喇叭,别喇叭的哑巴,不愿意拿喇叭换提拉塔嘛喇嘛的塔嘛。提拉塔嘛的喇嘛拿塔嘛打了别喇叭的哑巴一塔嘛,别喇叭的哑巴,拿喇叭打了提拉塔嘛的喇嘛一喇叭。也不知提拉塔嘛的喇嘛拿塔嘛打坏了别喇叭哑巴的喇叭。也不知别喇叭的哑巴拿喇巴打坏了提拉塔嘛喇嘛的塔嘛。提拉塔嘛的喇嘛敦塔嘛,别喇叭的哑巴吹喇叭"];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 3;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
// Configure the cell...
CGRect tempRect = cell.myLabel.frame;
CGFloat tempFloat = [self stringHeight:self.contentStr];
tempRect.size.height = tempFloat;
cell.myLabel.frame = tempRect;
cell.myLabel.text = self.contentStr;
cell.myLabel.numberOfLines = 0;
cell.myLabel.font = [UIFont systemFontOfSize:16];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return [self stringHeight:self.contentStr] + 20;
}
- (CGFloat)stringHeight:(NSString *)aString{
CGRect rect = [aString boundingRectWithSize:CGSizeMake(self.tableView.frame.size.width - 20, 2000) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:16.5]} context:nil];
// 选择size一定要大于等于实际的字体
return rect.size.height;
}
网友评论