• UITableView使用总结和性能优化



    UITableView有两种风格:UITableViewStylePlain和UITableViewStyleGrouped。

    如 果我们查看UITableViewCell的声明文件可以发现在内部有一个UIView控件(contentView,作为其他元素的父控件)、两个 UILable控件(textLabel、detailTextLabel)、一个UIImage控件(imageView),分别用于容器、显示内容、 详情和图片。

    这些子控件并不一定要全部使用,具体操作时可以通过UITableViewCellStyle进行设置。
    typedef NS_ENUM(NSInteger, UITableViewCellStyle) {
        UITableViewCellStyleDefault,    // 左侧显示textLabel(不显示detailTextLabel),imageView可选(显示在最左边)
        UITableViewCellStyleValue1,    // 左侧显示textLabel、右侧显示detailTextLabel(默认蓝色),imageView可选(显示在最左边)
        UITableViewCellStyleValue2,    // 左侧依次显示textLabel(默认蓝色)和detailTextLabel,imageView可选(显示在最左边)
        UITableViewCellStyleSubtitle    // 左上方显示textLabel,左下方显示detailTextLabel(默认灰色),imageView可选(显示在最左边)
    };

    有时候我们会发现很多UITableViewCell右侧可以显示不同的图标,在iOS中称之为访问器,点击可以触发不同的事件。
    要设置这些图标只需要设置UITableViewCell的accesoryType属性,这是一个枚举类型具体含义如下:
    typedef NS_ENUM(NSInteger, UITableViewCellAccessoryType) {
        UITableViewCellAccessoryNone,                   // 不显示任何图标
        UITableViewCellAccessoryDisclosureIndicator,    // 跳转指示图标
        UITableViewCellAccessoryDetailDisclosureButton, // 内容详情图标和跳转指示图标
        UITableViewCellAccessoryCheckmark,              // 勾选图标
        UITableViewCellAccessoryDetailButton NS_ENUM_AVAILABLE_IOS(7_0) // 内容详情图标
    };
    其他不在此之列的,比如UISwitch,通过设置cell.accessoryView=uiswitch即可。

    datasource实例见:http://www.cnblogs.com/kenshincui/p/3931948.html [好文章]

    ------------------------------------------------------- 分割线 -------------------------------------------------------

    1. 首先,Controller需要实现两个delegate ,分别是  UITableViewDelegate 和  UITableViewDataSource
    2. 然后 UITableView对象的 delegate要设置为 self。
    3. 然后就可以实现这些delegate的一些方法拉。

    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;  //这个方法返回分组数。  
    - (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section; //这个方法返回分组的行数。 
    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath; //这个方法返回指定的 row 的高度。
    - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section; // 这个方法返回指定的 section的header view 的高度。
    - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section; //这个方法返回指定的 section的footer view 的高度。

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
    {
        static NSString * showUserInfoCellIdentifier = @"ShowUserInfoCell";
        UITableViewCell * cell = [tableView_ dequeueReusableCellWithIdentifier:showUserInfoCellIdentifier];
        if (cell == nil)
        {
    #if0
        //代码
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle  reuseIdentifier:showUserInfoCellIdentifier];
        //在这里添加自定义子视图
    #elseif
         //xib注册
                cell=[[[NSBundle mainBundle]loadNibNamed:@"TabelViewCell" owner:nil options:nil] objectAtIndex:0];
    #endif
    }
        
        cell.textLabel.text=@"签名";
        cell.detailTextLabel.text = [NSString stringWithCString:userInfo.user_signature.c_str()  encoding:NSUTF8StringEncoding];

            return cell;
    }
            
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath; //当用户选中某个行的cell的时候,回调用这个
    TableView.allowsSelection=YES;  
    cell.selectionStyle=UITableViewCellSelectionStyleBlue;  

    - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section; //返回指定的section 的 header  的 title,如果这个section header  有返回view,那么title就不起作用了。

    - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section; //返回指定的 section header 的view,如果没有,这个函数可以不返回view

    - (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath; //这个函数响应,用户点击cell 右边的 箭头(如果有的话)

    - (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath; //返回当前cell  要执行的是哪种编辑

    -(void) tableView:(UITableView *)aTableView  commitEditingStyle:(UITableViewCellEditingStyle) editingStyle  forRowAtIndexPath:(NSIndexPath *)indexPath; //通知告诉用户编辑了 哪个cell

    - (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath; //获得 某一行的CELL对象

    -(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath; // 删除行

    -(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath; // 添加行

    -(void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath; // 移动

    - (void)reloadData;刷新整个表格。

    - (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation NS_AVAILABLE_IOS(3_0);刷新指定的分组和行。

    - (void)reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation NS_AVAILABLE_IOS(3_0);刷新指定的分组。

    - (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;//删除时刷新指定的行数据。

    - (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;//添加时刷新指定的行数据。

    ------------------------------------------------------- 分割线 -------------------------------------------------------

    在 UITableView内部有一个缓存池,初始化时使用initWithStyle:(UITableViewCellStyle) reuseIdentifier:(NSString *)方法指定一个可重用标识,就可以将这个cell放到缓存池。然后在使用时使用指定的标识去缓存池中取得对应的cell然后修改cell内容即可。

    UITableView得Cell里如果有尺寸比较大得图片,滑动得时候会有卡顿现象,什么原因?怎么解决?
    在主线程中去加载的,这样的话,因为阻塞了线程,所以导致的滑动卡顿,还有一点就是,因为表格的重绘机制,所以每次还要重新加载视图。

    优化途径:
    1. 使用不透明视图。
    不透明的视图可以极大地提高渲染的速度。因此如非必要,可以将table cell及其子视图的opaque属性设为YES(默认值)。
    其中的特例包括背景色,它的alpha值应该为1(例如不要使用clearColor);图像的alpha值也应该为1,或者在画图时设为不透明。

    2. 不要重复创建不必要的table cell。
    前面说了,UITableView只需要一屏幕的UITableViewCell对象即可。因此在cell不可见时,可以将其缓存起来,而在需要时继续使用它即可。
    而UITableView也提供了这种机制,只需要简单地设置一个identifier即可,而UITableView也提供了这种机制,只需要简单地设置一个identifier即可。
    cell被重用时,它内部绘制的内容并不会被自动清除,因此你可能需要调用setNeedsDisplayInRect:或setNeedsDisplay方法。

    3. 减少视图的数目。
    UITableViewCell包含了textLabel、detailTextLabel和imageView等view,而你还可以自定义一些视图放在它的contentView里。然而view是很大的对象,创建它会消耗较多资源,并且也影响渲染的性能。
    如果你的table cell包含图片,且数目较多,使用默认的UITableViewCell会非常影响性能。奇怪的是,使用自定义的view,而非预定义的view,明显会快些。
    当然,最佳的解决办法还是继承UITableViewCell,并在其drawRect:中自行绘制。
    此外还可以创建CALayer,将内容绘制到layer上,然后对cell的contentView.layer调用addSublayer:方法。这个例子中,layer并不会显著影响性能,但如果layer透明,或者有圆角、变形等效果,就会影响到绘制速度了。

    4. 不要做多余的绘制工作。
    在实现drawRect:的时候,它的rect参数就是需要绘制的区域,这个区域之外的不需要进行绘制。

    5. 预渲染图像。
    你会发现即使做到了上述几点,当新的图像出现时,仍然会有短暂的停顿现象。解决的办法就是在bitmap context里先将其画一遍,导出成UIImage对象,然后再绘制到屏幕。

    6. 不要阻塞主线程。
    主线程执行了耗时很长的函数或方法,在其执行完毕前,无法绘制屏幕和响应用户请求。其中最常见的就是网络请求了,它通常都需要花费数秒的时间,而你不应该让用户等待那么久。
    解 决办法就是使用多线程,让子线程去执行这些函数或方法。这里面还有一个学问,当下载线程数超过2时,会显著影响主线程的性能。因此在使用 ASIHTTPRequest时,可以用一个NSOperationQueue来维护下载请求,并将其 maxConcurrentOperationCount设为2。 

  • 相关阅读:
    封装一个通用递归算法,使用TreeIterator和TreeMap来简化你的开发工作。
    优化特性(Attribute)性能
    不需要了解任何底层知识,就可以汉化!Let`s go!!!
    颠覆你对方法调用的看法!
    实际项目中面向对象的最佳实践
    递归使用触发器
    关于稀疏数组
    121-django中的Http404处理
    120-在前端使用django-ckeditor,很简单,很方便
    119-用django实现评论功能
  • 原文地址:https://www.cnblogs.com/Ghosgt/p/5961273.html
Copyright © 2020-2023  润新知