【问题标题】:RxDataSources cell reload animations not working properlyRxDataSources 单元格重新加载动画无法正常工作
【发布时间】:2021-07-24 06:14:06
【问题描述】:

RxSwiftRxDataSources 单元重新加载动画有一些问题。我有一个简单的表格设置,如下所示:

import UIKit
import RxDataSources
import RxCocoa
import RxSwift
import Fakery

class ViewController1: UIViewController {


    @IBOutlet weak var tableView: UITableView!
    let bag = DisposeBag()



    override func viewDidLoad() {
        super.viewDidLoad()
        setupTableView()
    }

    private func setupTableView() {
        tableView.register(UINib(nibName: "TestTableViewCell", bundle: nil), forCellReuseIdentifier: "cell")

        let dataSource = RxTableViewSectionedAnimatedDataSource<SectionOfTestData>(
            animationConfiguration: AnimationConfiguration(insertAnimation: .none, reloadAnimation: .none, deleteAnimation: .none),
            configureCell: { dataSource, tableView, indexPath, element in
                let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TestTableViewCell
                cell.testData = element
                return cell
            })

        someData
            .bind(to: tableView.rx.items(dataSource: dataSource))
            .disposed(by: bag)
    }

    let someData = BehaviorRelay<[SectionOfTestData]>(value: [SectionOfTestData(items: [
        TestData(color: .red, name: "Henry"),
        TestData(color: .blue, name: "Josh")
    ])])

    @IBAction func didTapUpdateButton(_ sender: Any) {
        let colors: [UIColor] = [.blue, .purple, .orange, .red, .brown]


        let items = someData.value.first!.items

        // Add random data when button is tapped
        someData.accept([SectionOfTestData(items: items + [TestData(color: colors.randomElement()!, name: Faker().name.firstName())])])
    }

}

模型:

struct TestData {
    let color: UIColor
    let name: String
}

extension TestData: IdentifiableType, Equatable {
    typealias Identity = Int

    var identity: Identity {
           return Int.random(in: 0..<20000)
    }
}

struct SectionOfTestData {
    var items: [Item]

    var identity: Int {
        return 0
    }
}

extension SectionOfTestData: AnimatableSectionModelType {
    typealias Identity = Int
    typealias Item = TestData

    // Implement default init
    init(original: SectionOfTestData, items: [Item]) {
        self = original
        self.items = items
    }
}

class TestTableViewCell: UITableViewCell {

    @IBOutlet weak var colorView: UIView!
    @IBOutlet weak var nameLabel: UILabel!

    var testData: TestData! {
        didSet {
            colorView.backgroundColor = testData.color
            nameLabel.text = testData.name
        }
    }

}

当点击按钮时,BehaviorRelay 会更新并且表格似乎会刷新,但是“动画”总是相同的。在提供的代码中,我实际上将所有动画类型设置为.none,但它仍在执行动画。如果我尝试将动画类型更改为另一种类型,例如.bottom,动画是相同的。我在这里做错了什么?

这是 reload 动画还是 insert 动画?我不知道数据更新时表是否会重新加载或插入,我在文档中找不到任何信息。任何关于此的指针将不胜感激!

【问题讨论】:

    标签: ios swift rx-swift rxdatasources


    【解决方案1】:

    你的问题是:

    var identity: Identity {
        return Int.random(in: 0..<20000)
    }
    

    RxDataSources 使用标识值来计算变更集。 您已经以每次基本上都返回一个新值的方式实现它(除非您遇到冲突),因此从框架的角度来看,您总是删除所有项目并添加新项目。您可以通过实施来检查这一点

    decideViewTransition: { _, _, changeset in
        print(changeset)
        return .animated
    }
    

    【讨论】:

    • 不敢相信我没有注意到这一点!当然 id 是不同的,我每次调用随机函数时都在计算一个新的。谢谢!顺便说一句,您知道数据更改时是调用 reloadData 还是调用 insert row ?
    • 如果decideViewTransition 返回.animated,它会调用performBatchUpdates,并传递一个调用insertRowsdeleteRows 等的闭包,具体取决于变更集。如果decideViewTransition 返回.reload,它将调用reloadData
    • 谢谢!很有帮助。
    • 然而,对于 UICollection 视图,它似乎总是对所有样式使用淡入淡出动画。如果您有时间看stackoverflow.com/questions/59727464/…,我发布了另一个问题
    【解决方案2】:

    完成接受的答案:

    创建一个uuid 并将其传递给identity

    let id = UUID().uuidString
    var identity: String {
       return id
    }
    

    然后动画完美运行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-21
      • 2013-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多