美文网首页
关于UITableView

关于UITableView

作者: 不辣先生 | 来源:发表于2020-09-18 17:28 被阅读0次

    MARK1

    
    // Row display. Implementers should *always* try to reuse cells by setting each cell's reuseIdentifier and querying for available reusable cells with dequeueReusableCellWithIdentifier:
    // Cell gets various attributes set automatically based on table (separators) and data source (accessory views, editing controls)
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
    
    - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath;
    
    - (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath*)indexPath API_AVAILABLE(ios(6.0));
    
    

    关于这个代理,熟悉的不能再熟了,但是没想过它是怎么工作的
    测试机iPhone7 系统iOS13
    数据源10 和100
    发现这个方法不是你滑动的时候才加载cell,测试数据10,控制页面只能显示3个cell的时候其实这个方法给全部加载完了一遍,然后拖动的时候如果cell是从屏幕外进来的还会重新加载一遍,即它干了大量重复的工作,测试数据100的时候页面加载完成的时候,它走了14次。

    结论:页面加载完毕这个方法调用次数并不等于屏幕上预计可见cell的数量,调用具体数量不知道怎么控制的(可能根据机型性能),然后屏幕滑动加载新cell时候这个方法还是会调用,只是cell已经创建好了直接去缓存池中取,意思就是这个方法针对indexPath会重复调用;willDisplayCell这个接口同步跟在cellForRowAtIndexPath后面调用次数也一致,didEndDisplayingCell这个接口并不能很好的判断cell离开屏幕的时机,首先页面加载完毕可能会加载超出屏幕可见cell的数量,willDisplayCell会和cellForRowAtIndexPath调用相同的次数,如果创建的cell非可见,didEndDisplayingCell这个方法又会被触发,其次这个方法并不能完美的契合cell离开屏幕时候就去触发的时机(感觉不到这个方法存在的意义,可能是我使用的姿势不对),建议通过scrollViewDidScroll这个接口去计算滚动距离和屏幕高度来处理

    MARK2

    UITableView style为grouped的时候重写frame去实现cell间距和边距效果的时候,会有不可预知的效果;另外cell需要编辑的时候也是一样(能不用grouped就不用,不可预期的bug太多);

    先上个bug图: IMG_0181.jpg
    图中有两个问题,问题一,第二组的第一个cell的顶部出现了一个分割线,其实那个cell已经设置了去掉分割线的代码
    cell.separatorInset = UIEdgeInsets.init(top: 0, left: 0, bottom: 0, right: CGFloat(MAXFLOAT))
    

    但是上面还有条线,最后是加了一行代码

            tb.separatorStyle = .none
    

    问题二,明显能感觉到 第二个section header高度有问题(其实不是header高度问题是第一个section的最后一个cell的下面多了空白,为啥说是cell没说sectionfooter呢?因为我给sectionFooter通过代理返回一个0.001并没卵用,然后第二个section的第一个cell的上面也有空白,UI看上去像是header高度变了),tableView为grouped状态,原因是:重写了第二个section下的cell的frame,但是如果tablview style 为 plain的时候是正常的,这他妈就跟玄学一样,因为苹果也没告诉你tableview是怎么去布局上面的cell的,何时会触发setFrame(会调用很多次),最后怎么”解决“的呢?我继承UIview自定义了header重写frame,把Y往上调了,高度调小了,然后代理返回的高度改小了,具体看代码吧

    //自定义的header
    class SectionHeader: UIView {
    
        override var frame: CGRect{
            get {
                return super.frame
            }
            set {
                var rect: CGRect = newValue
                rect.origin.y -= 16
                rect.size.height += 32
                 
                super.frame = rect
            }
        }
    
    }
    //代理返回的高度
     func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
            if section == 1 {
                          
                return CGFloat(24.0^&)
    
            }
    //代理返回的header
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
            if self.decDetailModel.ownerInformation.count == 0 {//请求失败没有获取到数据
                return UIView()
            }
            if section == 0 {
                return UIView()
            }
            let header = SectionHeader.init(frame: CGRect.init(x: 0, y: 0, width: Int(Screen_width), height: Int(56^&)))
    

    为啥解决带了引号了,因为这玩意看起来像是解决了(UI展示达到预期了),但是不可控,你不知道为啥这样可以了,真特么的蛋疼,建议如果遇到类似这种需要组头然后cell又需要做缩进处理留边的,直接通过给cell加空白填充效果处理吧,虽然笨,但是至少是可控的
    补:

    tb.estimatedRowHeight = 0
    tb.estimatedSectionFooterHeight = 0
    tb.estimatedSectionHeaderHeight = 0
    

    添加这三项设置后cell布局没了那种不可预知的空白或者留白,可能是这三个有默认值的关系,建议如果不影响每次都给tableview带上这三设置吧
    问题三、刷新界面不带动画

    DispatchQueue.main.async {
          UIView.performWithoutAnimation {
               self.myTableView.reloadRows(at: [index], with: .none)
           } 
     }
    注:很神奇的是必须要主线程异步执行不然界面会闪动(就算你本来是在主线程,难道执行时机会有影响?),位置还会上下偏移
    

    问题四:调用删除api 崩溃

         self.myTableView.deleteRows(at: indexs, with: .fade)
    

    解决:必须先更新数据源,然后再delete
    tableView编辑状态

    相关文章

      网友评论

          本文标题:关于UITableView

          本文链接:https://www.haomeiwen.com/subject/ravjyktx.html