zoukankan      html  css  js  c++  java
  • UI基础之UITableView的基本使用

    UITableView控件

    1,基本使用(required)

    UITableView有两种样式:grouped/plain 组/单行

    UITableView需要⼀一个数据源(dataSource)来显示数据
    UITableView会向数据源查询一共有多少行数据以及每⼀行显示什么数据等

    没有设置数据源的UITableView只是个空壳

    凡是遵守UITableViewDataSource协议的OC对象,都可以是UITableView的数据源  

    展示数据的过程:

    (1)调用数据源的下面⽅法得知⼀一共有多少组数据
    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;

    (2)调用数据源的下面⽅法得知每一组有多少行数据
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;

    (3)调⽤数据源的下⾯⽅法得知每⼀⾏显示什么内容

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;

    2,UITableView的常用属性

    (1)设置分割样式和边距(tableview.separatorStyle),这是个枚举类型

     separatorInset

    (2)设置分割线的颜色,可以直接使用系统给出的颜色,如果系统给定的颜色不能满足需求时,也可以自定义。

      补充:颜色分为24位和32位的,如下

      24bit颜色

         R 8bit 0 ~ 255

         G 8bit 0 ~ 255

         B 8bit 0 ~ 255

         32bit颜色

         A 8bit 0 ~ 255(tou)

         R 8bit

         G 8bit

         B 8bit     

         #ff ff ff 白色

         #00 00 00 黑色

         #ff 00 00 红色

         #255 00 00

     设置为自定义颜色的实例:tableview.separatorColor = [UIColorcolorWithRed:0/255.0green:255/255.0blue:0/255.0alpha:255/255.0];

     //接收的参数是颜色的比例值

     (3)设置顶部和底部视图

    tableview.tableHeaderView   //顶部

    tableview.tableFooterView    //底部

    4)设置cell的高度

    tableView.rowHeight  // cell高度

    5)每一组的头部、尾部高度

    sectionHeaderHeight

    sectionFooterHeight

    6)背景颜色两个属性

    backgroundView(优先级高)

    backgroundColor(优先级低)

    默认tableView设置颜色会被它上面cell挡住,可以设置cell的透明度

    7)刷新数据

    reloadData(整个tableView的数据)

    - (void)reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation

    (刷新某一个组某一行的数据)

    3,UITableViewCell的常用属性

     UITableViewCell内部用一个contentView属性在contentview中默认有三个子视图:

    第2个是UILabel(通过UITableViewCell的textLabel和detailTextLabel属性访问)

    第3个是UIImageView(通过UITableViewCell的imageView属性访问)

     UITableViewCell还有⼀个UITableViewCellStyle属性,⽤于决定使用contentView的哪些子视图,以及这些子视图在contentView中的位置 

    1)辅助视图

    1)设置cell的辅助视图,设置cell.accessoryView(系统提供了枚举型,也可以自定义@父类指针指向子类对象);

    2,设置cell的背景颜色两种属性

    backgroundColor/ backgroundView

    选中状态的颜色

    selectedbackgroundView(color)

    4 常用的数据源方法和代理方法

    数据源方法

     代理方法:

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;

    - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section;

     - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section;

    - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section;  

     - (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath; 

    - (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath

    5,UITableViewCell的性能问题

     问题cell的工作:在程序执行的时候,能看到多少条,它就创建多少条数据,如果视图滚动那么再创建新显示的内容。(系统自动调用)。即当一个cell出现在视野范围内的时候,就会调用创建一个cell。这样

     cell重用原理 :当滚动列表时,部分UITableViewCell会移出窗口,UITableView会将窗口外的UITableViewCell放入一个对象池中,等待重用。当UITableView要求dataSource返回 UITableViewCell时,dataSource会先查看这个对象池,如果池中有未使用的UITableViewCell,dataSource则会用新的数据来配置这个UITableViewCell,然后返回给 UITableView,重新显示到窗口中,从而避免创建新对象 

    注意点:对象池中也会有很多不同类型的 UITableViewCell,那么UITableView在重⽤用UITableViewCell时可能会得到错误类型的 UITableViewCell

    解决方案:UITableViewCell有个NSString *reuseIdentifier属性,可以在初始化UITableViewCell的时候传入一个特定的字符串标识来设置reuseIdentifier(一般用UITableViewCell的类名)。当UITableView要求dataSource返回UITableViewCell时,先 通过一个字符串标识到对象池中查找对应类型的UITableViewCell对象,如果有,就重用,如果没有,就传入这个字符串标识来初始化⼀一个UITableViewCell对象。

    缓存优化的思路:

    (1)先去缓存池中查找是否有满足条件的cell,若有那就直接拿来

    (2)若没有,就自己创建一个cell

    (3)创建cell,并且设置一个唯一的标记(把属于“”的给盖个章)

    (4)给cell设置数据

    注意点:

    定义变量用来保存重用标记的值,这里不推荐使用宏(#define来处理),因为该变量只在这个作用域的内部使用,且如果使用宏定义的话,定义和使用位置太分散,不利于阅读程序。由于其值不变,没有必要每次都开辟一次,所以用static定义为一个静态变量。

    6,刷新数据的两个步骤:

       1)修改模型

       2)刷新表格数据(可以全部刷新,也可以刷新指定的行)

    代码案例:

    数据模型:

    #import <Foundation/Foundation.h>
    
    @interface LLHeroList : NSObject
    
    @property (nonatomic, copy) NSString *icon;
    @property (nonatomic, copy) NSString *intro;
    @property (nonatomic, copy) NSString *name;
    
    - (instancetype)initWithDic:(NSDictionary *)dic;
    + (instancetype)heroListWithDic:(NSDictionary *)dic;
    
    + (NSMutableArray *)heroesList;
    
    @end
    #import "LLHeroList.h"
    
    @implementation LLHeroList
    
    - (instancetype)initWithDic:(NSDictionary *)dic
    {
        if (self = [super init]) {
            [self setValuesForKeysWithDictionary:dic];
        }
        return self;
    }
    
    + (instancetype)heroListWithDic:(NSDictionary *)dic
    {
        return [[self alloc] initWithDic:dic];
    }
    
    + (NSMutableArray *)heroesList
    {
        NSString *path = [[NSBundle mainBundle] pathForResource:@"heros" ofType:@"plist"];
        NSArray *dicArr = [NSArray arrayWithContentsOfFile:path];
        
        NSMutableArray *tmpArr = [[NSMutableArray alloc] initWithCapacity:dicArr.count];
        for (NSDictionary *dic in dicArr) {
            
            LLHeroList *hero = [LLHeroList heroListWithDic:dic];
            
            [tmpArr addObject:hero];
        }
        return tmpArr;
    }
    
    @end

    controller:

    #import "ViewController.h"
    #import "LLHeroList.h"
    @interface ViewController ()<UITableViewDataSource, UITableViewDelegate, UIAlertViewDelegate, UIActionSheetDelegate>
    
    @property (nonatomic, strong) NSMutableArray *heroes;
    @property (nonatomic, weak) UITableView *tableView;
    
    @end
    
    @implementation ViewController
    
    - (NSMutableArray *)heroes
    {
        if (!_heroes) {
            
            _heroes = [LLHeroList heroesList];
        }
        return _heroes;
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
        
        [self loadTableView];
    }
    
    - (void)loadTableView
    {
        UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) style:UITableViewStylePlain];
        [self.view addSubview:tableView];
        self.tableView = tableView;
        
        self.tableView.dataSource = self;
        self.tableView.rowHeight = 60;
        
        // tableView的代理
        self.tableView.delegate = self;
        
        // tableView分割线颜色设置:
        self.tableView.separatorColor = [UIColor colorWithRed:0/255.0 green:255/255.0 blue:0/255.0 alpha:1];
        // 设置分割线的内边距
        self.tableView.separatorInset = UIEdgeInsetsMake(0, 0, 0, 0);
    }
    
    #pragma mark - 数据源方法
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        return self.heroes.count;
        
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        static NSString *ID = @"hero";
        UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:ID];
        
        if (!cell) {
            
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
        }
        
        LLHeroList *hero = self.heroes[indexPath.row];
        cell.imageView.image = [UIImage imageNamed:hero.icon];
        cell.textLabel.text = hero.name;
        cell.detailTextLabel.text = hero.intro;
        
        // 给cell添加辅助按钮
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
        
        // 给cell添加背景图片
        cell.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"buttonorange"]];
        // 设置cell选中的颜色
        cell.selectedBackgroundView =  [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"buttonred"]];
        
        return cell;
    }
    
    #pragma mark - tableView的代理方法
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
    //    // 1,创建一个alertView对象
    //    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"英雄展示" message:nil delegate:self cancelButtonTitle:@"cancle" otherButtonTitles:@"ok", nil];
    //    
    //    // 2,设置alertView的样式(3中样式)
    //    alertView.alertViewStyle = UIAlertViewStylePlainTextInput;
    //    
    //    // 3,设置alertView文本输入框展示的内容
    //    [alertView textFieldAtIndex:0].text = [self.heroes[indexPath.row] name];
    //    
    //    // 4,给alertView的代理方法传递当前选中行的行号
    //    alertView.tag = indexPath.row;
    //    [alertView show];
        
        UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:@"英雄展示" delegate:self cancelButtonTitle:@"cancel" destructiveButtonTitle:@"删除英雄" otherButtonTitles:@"ok" ,nil];
        sheet.tag = indexPath.row;
        
        [sheet showInView:[[UIView alloc] init]];
    }
    
    #pragma mark - alertView的代理方法
    - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
    {
        if (buttonIndex == 0) return;
        
        // 修改数据模型
        LLHeroList *hero = self.heroes[alertView.tag];
        hero.name = [alertView textFieldAtIndex:0].text;
        
        // 刷新表格
    //    // 全部刷新
    //    [self.tableView reloadData];
        // 局部刷新
        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:alertView.tag inSection:0];
        [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationBottom];
        
    }
    
    #pragma mark - actionSheet代理方法
    - (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
    {
        if (buttonIndex == 0) {
            
            [self.heroes removeObjectAtIndex:actionSheet.tag];
            [self.tableView reloadData];
        }
    }
    
    @end

    效果:

  • 相关阅读:
    Linux就该这么学——新手必须掌握的命令之文件目录管理命令组
    Linux就该这么学——新手必须掌握的命令之文件编辑命令组
    Linux就该这么学——新手必须掌握的命令之工作目录切换命令组
    Linux就该这么学——新手必须掌握的命令之系统状态检测命令组
    Linux就该这么学——新手必须掌握的命令之常用的系统工作命令
    Linux就该这么学——新手必须掌握的命令之我的第一个命令
    Linux就该这么学——安装配置VM虚拟机
    thinkphp6下无法获取header头中的Authorization(apache版)
    字符串转数组(php版)
    python3 第二十二章
  • 原文地址:https://www.cnblogs.com/-boy/p/4121984.html
Copyright © 2011-2022 走看看