UIKit之UITableView

2017-07-20  本文已影响0人  MI移动

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;
}

上一篇下一篇

猜你喜欢

热点阅读