简体   繁体   English

调用tableView.reloadData()删除自定义单元内动画

[英]Calling tableView.reloadData() removes custom in-cell animation

My app is written in Swift 2.0 and needs to run on iOS 8.1 or higher. 我的应用程序是用Swift 2.0编写的,需要在iOS 8.1或更高版本上运行。 I use Xcode 7.0. 我使用Xcode 7.0。

I am using a standard UITableViewController. 我正在使用标准的UITableViewController。 My UITableView has only one kind of custom prototype cells CustomCell that subclasses UITableViewCell. 我的UITableView只有一种自定义原型单元CustomCell,它是UITableViewCell的子类。 The CustomCell has a couple of UILabels inside, all of them have clear background colour and fixed width and height. CustomCell内部有几个UILabel,它们都有清晰的背景色和固定的宽度和高度。 Everything is laid out in the Interface Builder. 一切都在界面生成器中进行布局。

I receive data very often (10+ times/s) from another source. 我经常从另一个来源接收数据(10次以上)。 The labels in my cell have to update their content based on the received data. 我单元格中的标签必须根据收到的数据更新其内容。 I also need to animate the labels backgrounds colours. 我还需要为标签的背景颜色设置动画。 To do this, I use the following: 为此,我使用以下方法:

extension UIView {   
    func fadeOut() {
        self.layer.backgroundColor = UIColor.blackColor().CGColor
        UIView.animateWithDuration(2.0, delay: 0.0, options: UIViewAnimationOptions.CurveEaseOut, animations: { () -> Void in
            self.layer.backgroundColor = UIColor.clearColor().CGColor
        }, completion: nil)
    }
}

I update the labels using the following code: 我使用以下代码更新标签:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("customCell", forIndexPath: indexPath) as! CustomCell
    let oldText = customLabel.text
    let newText = dataForLabels[indexPath.row].custom
    if newText != oldText {
        cell.customLabel.fadeOut()
    }
    cell.customLabel.text = dataForLabels[indexPath.row].custom
    return cell
}

And my update (callback) method looks like this: 我的更新(回调)方法如下所示:

var dataForLabels:[Int:(custom: String?, anotherCustom: String?)] = [:]

func updateData(CustomData data) {
    for d in data {
        dataForLabels[d.index] = (custom: data.custom, anotherCustom: data.anotherCustom)
    }
    tableView.reloadData()
}

Now, the problem itself: 现在,问题本身:

When there is no change in data for specific cell/label, the animation should go on (fading effect, 2s). 如果特定单元格/标签的数据没有变化,则动画应继续播放(渐变效果为2秒)。 When the data changes, the animation should restart. 数据更改时,动画应重新启动。

When I call reloadData(), and there was no change of data, the animation is removed/stopped, that is, the label's background colour is suddenly clear with no fading effect. 当我调用reloadData()且数据没有变化时,动画将被删除/停止,也就是说,标签的背景颜色突然变得清晰,没有褪色效果。

I have tried dispatching reloadData() to the main thread, but it doesn't help. 我尝试将reloadData()调度到主线程,但这无济于事。 I have tried using CABasicAnimation instead of animateWithDuration(), but it doesn't solve the problem either. 我尝试使用CABasicAnimation代替animateWithDuration(),但是它也不能解决问题。

I tried a similar scenario, but without using a table at all (just a couple of UIViews instead of cells) and it works. 我尝试了类似的情况,但是根本没有使用表(只是几个UIView而不是单元格),并且它可以工作。 The problem is when I use reloadData(). 问题是当我使用reloadData()时。

I have tried debugging it, but I am not good when it comes to disassembly. 我已经尝试调试它,但是在拆卸方面我并不擅长。 I saw that layout_if_needed() was called and somewhere there all animations were removed. 我看到调用了layout_if_needed(),并删除了所有动画。

What I suspect is that when reloadData() is called, the layout manager thinks that for some reason constraints changed and there is a need to update the layout, which breaks all animations. 我怀疑的是,当调用reloadData()时,布局管理器认为由于某种原因约束发生了变化,因此需要更新布局,这会破坏所有动画。

Is there any solution to this problem, preferably one where I can keep using Interface Builder? 有没有解决此问题的方法,最好是可以继续使用Interface Builder的方法?

Any help will be greatly appreciated. 任何帮助将不胜感激。

You do not need to reload the tableview if data on the labels change, just change the text on the labels. 如果标签上的数据发生更改,则无需重新加载表格视图,只需更改标签上的文本即可。 You need only to reload the tableview if eg the count of rows changes or you need to re-create the cells. 仅在例如行数更改或您需要重新创建单元格时才需要重新加载tableview。

Just get the index paths of the visible rows with tableView.indexPathsForVisibleRows and iterate over the visible cells to change text or background. 只需使用tableView.indexPathsForVisibleRows获取可见行的索引路径,然后遍历可见单元格即可更改文本或背景。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM