标签: diffabledatasource

UITableViewDiffableDataSource 可以检测到更改的项目吗?

(在与下面的@AndreasOetjen 讨论后重写了这个问题。感谢他的评论。)

我在使用UITableViewdiffable 数据源时遇到了问题。在我的应用程序中,当用户修改一个项目时,它可能会更改同一表视图中显示的另一个项目。问题是,在我创建并应用包含两个项目的新值的新快照后,间接更改的项目的 UI 没有更新。

起初我认为 diffable 数据源能够检测不同快照中项目的值变化。例如,它可能以这种方式工作:如果它发现两个快照包含相同的项目(即,两个快照中的项目具有相同的哈希值),则比较它们的值并在值更改时更新表视图中该项目的行。但是,后来我意识到它可能不会那样工作,因为 diffable 数据源没有定义任何 API 来获取和比较项目值(我最初的想法是它使用了description计算属性和==操作,但现在我认为这不是真的)。

所以我目前的理解是 diffable 数据源使用项目的散列来检测项目顺序变化(即插入新项目,旧项目仍然存在等),而不是项目值变化(即旧项目仍然存在但其值已更改)。如果这种理解是正确的,那么就引出了这个问题:如何使用diffable数据源来实现以下场景?

  • 一个项目有几个属性。一个属性(我们称之为属性 A)显示在 UI 中,但不用于生成哈希。
  • 该项目存在于旧快照和新快照中,但其属性 A 发生了变化。所以它的用户界面需要更新。

在旧UITableViewAPI 中,这可以通过调用reloadRows()或来实现reloadData()。但是如何使用 diffable 数据源来做到这一点?

更新

在花时间做实验并解决问题后,我认为上述问题的理解是错误的。请看我下面的回答。我相信这解释了 diffable 数据源的工作原理。我希望它对其他有同样困惑的人有所帮助。我很高兴被证明是错误的。真的。因此,如果您有不同的想法,请留下您的答案。

uitableview uikit ios uicollectionview diffabledatasource

5
推荐指数
1
解决办法
2944
查看次数

如何通过DiffableDataSource更新Section中的页脚而不会造成闪烁效果?

一个部分可能包含 1 个页眉、许多内容项和 1 个页脚。

对于DiffableDataSource,网上的大部分例子,都是enum用来表示Section的。例如

func applySnapshot(_ animatingDifferences: Bool) {
    var snapshot = Snapshot()
    
    snapshot.appendSections([.MainAsEnum])

    snapshot.appendItems(filteredTabInfos, toSection: .MainAsEnum)

    dataSource?.apply(snapshot, animatingDifferences: animatingDifferences)
}
Run Code Online (Sandbox Code Playgroud)

但是,当 Section 有动态内容页脚时,我们可能需要使用 struct 来表示 Section。例如

import Foundation

struct TabInfoSection {

    // Do not include content items [TabInfo] as member of Section. If not, any mutable 
    // operation performed on content items, will misguide Diff framework to throw 
    // away entire current Section, and replace it with new Section. This causes 
    // flickering …
Run Code Online (Sandbox Code Playgroud)

ios swift diffabledatasource

5
推荐指数
1
解决办法
377
查看次数

无法在iOS 13中使用可扩散数据源通过TableView滑动以删除

我正在更新,UITableViewController以使用新的UITableViewDiffableDataSource,但所有工作都正常,但要滑动删除即可。

这是我如何使用滑动删除的示例

func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {

   let lockedAction = UIContextualAction(style: .normal, title: "TEST") { (_, _, completion) in
       print("tapped....")
       completion(true)
   }

    return UISwipeActionsConfiguration(actions: [lockedAction])
}
Run Code Online (Sandbox Code Playgroud)

但这在UITableViewController具有UITableViewDiffableDataSource

没有滑动,方法中的断点也不会被调用

我以为这是一个Beta错误,但是我更新到了Xcode 11 GM,并且发生了同样的事情。

感谢您的任何建议

uitableview swift ios13 diffabledatasource

4
推荐指数
2
解决办法
451
查看次数

使用 UITableViewDiffableDataSource 创建部分标题

我正在修修补补,UITableViewDiffableDataSource并且能够毫无问题地加载 tableView。我正在尝试在 tableView 中创建节标题,但是我遇到了一些奇怪的行为。

节 enum enum 定义如下:

    enum AlertLevel: String, Codable, CaseIterable {
        case green = "green"
        case yellow = "yellow"
        case orange = "orange"
        case red = "red"
    }
Run Code Online (Sandbox Code Playgroud)

这是我的实现 tableView(viewForHeaderInSection:)

    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let label = UILabel()
        label.text = dataSource.snapshot().sectionIdentifiers[section].rawValue.capitalized
        label.textColor = UIColor.black

        return label
    }
Run Code Online (Sandbox Code Playgroud)

这给了我 4 个标签堆叠在我的 tableView 顶部的标题单元格中。

我启动了 Dash 到 RTFD,我看到了tableView(titleForHeaderInSection:)另一种剥猫皮的方法。所以我把这个扔进去,而不是:

    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return …
Run Code Online (Sandbox Code Playgroud)

diff uitableview ios swift diffabledatasource

4
推荐指数
1
解决办法
876
查看次数

将 NSDiffableDataSourceSnapshot 应用于 UICollectionViewDiffableDataSource 会导致“NSInternalInconsistencyException”

我正在尝试UICollectionViewDiffableDataSource为我的collectionView. 我的代码编译得很好,但是我第一次对它应用快照时一直遇到这个错误,并出现以下错误:

由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“无效参数不满足:self.supplementaryViewProvider || (self.supplementaryReuseIdentifierProvider && self.supplementaryViewConfigurationHandler)'

这是我的代码:

    var groups: [Group] = [Group]()
    var dataSource: UICollectionViewDiffableDataSource<Section, Group>!

    // MARK: - View Life Cycle
    override func viewDidLoad() {
        super.viewDidLoad()

        self.searchBar.delegate = self
        self.groups = DummyData.groups

        setupDataSource()
    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        performSearch(searchQuery: nil)
    }


    // MARK: - Helper Functions
    func performSearch(searchQuery: String?) {
        let filteredGroups: [Group]
        if let searchQuery = searchQuery, !searchQuery.isEmpty {
            filteredGroups = groups.filter { $0.contains(query: searchQuery) }
        } else {
            filteredGroups = groups …
Run Code Online (Sandbox Code Playgroud)

uikit uicollectionview swift5 diffabledatasource nsdiffabledatasourcesnapshot

4
推荐指数
1
解决办法
1696
查看次数

Diffable 数据源 - 重新加载标头

可以通过哪些方式UICollectionViewDiffableDataSource重新加载标头?

我有一个集合视图,其中的标题显示用户详细信息,行显示帖子,模型是

struct PostUser {
    var user: User
    var post: Post
}
Run Code Online (Sandbox Code Playgroud)

当我通过快照更改属性时

    var postUsers = [PostUser]() {
        didSet {
            self.applySnapshot(postUsers)
        }
    }

    fileprivate func applySnapshot(_ postsUser: [PostUser]) {
        var snapshot = NSDiffableDataSourceSnapshot<Section, PostUser>()
        snapshot.appendSections([.main])
        snapshot.appendItems(postsUser)
        self.datasource.apply(snapshot, animatingDifferences: true)
    }
Run Code Online (Sandbox Code Playgroud)

行会重新加载,但补充标题不会重新加载。我可以更改标题的唯一方法是使“部分”成为模型的一部分,因此:

    struct Section: Hashable {
        var User: User
    }
Run Code Online (Sandbox Code Playgroud)

我的应用快照现在变成

    fileprivate func applySnapshot(_ postsUser: [PostUser]) {
        var snapshot = NSDiffableDataSourceSnapshot<Section, PostUser>()
        snapshot.appendSections([Section(User: self.user)])
        snapshot.appendItems(postsUser)
        self.datasource.apply(snapshot, animatingDifferences: true)
    }
Run Code Online (Sandbox Code Playgroud)

然后我单独设置用户

    var user: User! = nil {
        didSet {
            self.applySnapshot(self.postUsers) …
Run Code Online (Sandbox Code Playgroud)

ios swift diffabledatasource uicollectionviewdiffabledatasource

4
推荐指数
1
解决办法
2579
查看次数

如何在 UITableViewDiffableDataSource 中添加标题名称

我尝试为 中的每个部分添加标题UITableView,但在这种情况下UITableViewDiffableDataSource,我不知道应该在哪里做。我的代码的一部分:

private func prepareTableView() {
    tableView.delegate = self
    tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
    dataSource = UITableViewDiffableDataSource<Sections, User>(tableView: tableView, cellProvider: { (tableView, indexPath, user) -> UITableViewCell? in
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        cell.textLabel?.text = user.name
        return cell
    })
}

private func addElement(_ user: User) {
    var snap = NSDiffableDataSourceSnapshot<Sections, User>()
    snap.appendSections([.main, .second])
    if isFirst {
        users.append(user)
    } else {
        secondUsers.append(user)
    }
    snap.appendItems(users, toSection: .main)
    snap.appendItems(secondUsers, toSection: .second)
    isFirst.toggle()
    dataSource.apply(snap, animatingDifferences: true, completion: nil)
    dataSource.defaultRowAnimation = .fade …
Run Code Online (Sandbox Code Playgroud)

uitableview swift diffabledatasource nsdiffabledatasourcesnapshot

3
推荐指数
1
解决办法
1551
查看次数

*** 由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“致命:提供的标识符不是唯一的。” ***

大家好???我正在将以下内容解析JSONUITableView使用 aUITableViewDiffableDataSource进行漂亮的搜索动画。

JSON:https : //www.pathofexile.com/api/trade/data/items

这是回购:https : //github.com/laurentdelorme/PathOfData

从 JSON 中,我能够加载所有 13 个不同的类别,如模型文件中映射的那样。然后我能够将这些类别中的数据推送到另一个 tableView(使用 的那个UITableViewDiffableDataSource)并很好地显示所有内容。

但是,当我尝试将其内容推送到 DetailViewController 时,有一个类别会使我的应用程序崩溃,即初始ViewController.

这是我的模型:

struct ItemCategories: Codable {
    var result: [ItemCategory]
}

struct ItemCategory: Codable {
    var label: String
    var entries: [Item]
}

struct Item: Codable, Hashable {
    var name: String?
    var type: String?
    var text: String?
}
Run Code Online (Sandbox Code Playgroud)

这是我的 ViewController :

import UIKit

class ViewController: UITableViewController {

    let urlString = "https://www.pathofexile.com/api/trade/data/items"
    var categories …
Run Code Online (Sandbox Code Playgroud)

json uitableview ios swift diffabledatasource

2
推荐指数
1
解决办法
4340
查看次数

diffable collection view 如何在多个部分显示相同的项目?

我的应用程序提供了一个类似于 Apple 的表情符号键盘,其中表情符号按类别显示。我使用一个集合视图来呈现它,其中类别是部分。如果最近插入了表情符号,它应该出现在“常用”类别以及它通常所在的任何类别中。

这对我试图将我的集合视图转换为使用 a 来说是一个问题UICollectionViewDiffableDataSource,因为NSDiffableDataSourceSnapshot要求项目是唯一的。如果我做类似的事情

let snapshot = NSDiffableDataSourceSnapshot<Section, Emoji>()
snapshot.appendItems([thumbsUpEmoji], toSection: .frequents)
snapshot.appendItems([thumbsUpEmoji], toSection: .smileys)
dataSource.apply(snapshot)
Run Code Online (Sandbox Code Playgroud)

我收到类似的警告

插入的标识符已经存在;现有项目将被移动到此当前插入的位置。请注意,如果插入时项目不是唯一的,这将影响性能。

表情符号只出现在一个部分,而不是两个部分。如何将项目插入多个部分?

ios swift diffabledatasource

0
推荐指数
1
解决办法
672
查看次数