非常规使用 UITableView, reloadSections时动画效果异常

2 篇文章 0 订阅

直接上现象:

这里写图片描述

可以看到在调用reloadSections方法更新Section 2时,由于Section 1 只有一个Header区域,没有对应的Cell, 从而引起了这个现象。更新调用的方法如下:

func reloadSection2(_ sender: UIButton) {
        tableView.reloadSections(IndexSet.init(integer: 2), with: .automatic)
    }

问题说明

按照通常的逻辑关系,没有行数的Section压根就不应该创建相关的UI,但在实际应用时,由于数据获取和UI显示的不同步或者某些历史原因,导致我们先给UI占了位,等数据获取后再刷新显示,这就出现了上面所说的场景和现象了。

如果情况只是这样,那还好搞。但事实是,有时候你还在Section没有内容的时候把那个Section Header给隐藏起来了,这就给定位问题带来了很大的麻烦。我和我的小伙伴花了整整一天,才在项目中找到原因,简直累死。现在做了Demo来演示这个问题。

解决方案1 - 取消动画的方式

  • 全局刷新TableView:
    func reloadSection2(_ sender: UIButton) {
        tableView.reloadData()
    }

效果:

这里写图片描述

  • 强制取消reloadSections的动画效果:
    func reloadSection2(_ sender: UIButton) {
        UIView.performWithoutAnimation {
            tableView.reloadSections(IndexSet.init(integer: 2), with: .automatic)
        }
    }

效果:

这里写图片描述

可是如果我们非要保留这个过渡动画呢?

你没有看错,需求有时就是这个样子的,所以才会发生流血事件 -_-#

解决方案2 - 保留动画效果

  • 给空Section指定一个行,并通过设置高度控制显示/隐藏
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if section == 1 {
            return 1 //强制给Section 1指定一行Cell
        }
        return 3
    }

    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        if indexPath.section == 1 {
            return 0 //通过控制Section 1的Cell的高度来隐藏这个指定的Cell
        }
        return 40
    }

效果:

这里写图片描述

如果你把动画放慢,会发现在动画过程中,Section 1强制指定的的Cell有时会在动画初期出现,这个是由于ViewclipsToBounds没有设置的缘故,导致视图的内容可以在边界外显示出来。我们可以给Cell设置这个属性,以消除这个影响:

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)

        cell.textLabel?.text = self.randomSmallCaseString(length: 20);
        cell.backgroundColor = UIColor.green
        cell.clipsToBounds = true; // 设置这个属性,那内容限制在视图的边框内部不会越界显示
        return cell
    }

Demo下载 - Raspberry Pi

Demo - CSDN附件

这种方法不官方,但确实可行,是目前我想到的保留动画的解决方式。如果你们有其它的解决方式,请一定通知我: <824219521@qq.com>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值