diffable 数据源节标题在更新期间闪烁

2024-06-27

我目前面临的问题是,当将新快照应用于当前数据源时,页眉、页脚和装饰视图不是集合视图子视图的一部分,这可以被视为奇怪的闪烁。以前有人遇到过这个问题吗?

我通过以下方式更新数据源:

    var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
    snapshot.appendSections(Sections.allCases)
    items.forEach { snapshot.appendItems([$0], toSection: ItemSectionMapper.getSection(for: $0)) }
    self.dataSource?.apply(snapshot)

EDIT: It only seems to happen on iOS 14 devices.

编辑2: 以下是示例项目中同一问题的屏幕录制:https://i.stack.imgur.com/YzTWU.jpg https://i.stack.imgur.com/YzTWU.jpg

下面是它的代码:

import UIKit

// MARK: - Cell -

final class Cell: UICollectionViewCell {
    static let reuseIdentifier = "Cell"

    var isExpanded = false {
        didSet { label.numberOfLines = numberOfLines }
    }

    var numberOfLines: Int { isExpanded ? 0 : 3 }

    lazy var label: UILabel = {
        let label = UILabel()
        label.numberOfLines = numberOfLines
        label.frame.size = contentView.bounds.size
        label.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        return label
    }()

    override init(frame: CGRect) {
        super.init(frame: frame)
        contentView.addSubview(label)
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func sizeThatFits(_ size: CGSize) -> CGSize {
        label.sizeThatFits(size)
    }
}

final class Header: UICollectionReusableView {
    static let elementKind = "Header"
    
    lazy var label: UILabel = {
        let label = UILabel()
        label.numberOfLines = 1
        label.frame.size = bounds.size
        label.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        return label
    }()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        addSubview(label)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func sizeThatFits(_ size: CGSize) -> CGSize {
        label.sizeThatFits(size)
    }
}

// MARK: - UIViewController -

class ViewController: UIViewController {
    struct Item: Hashable {
        let text: String
        var isExpanded = false
        private let uuid = UUID()
    }

    var items: [Item] = [
        .init(
            text: """
            Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
            incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis
            nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
            Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore
            eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident.
            """
        ),
        .init(
            text: """
            Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
            incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis
            nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
            Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore
            eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident.
            """,
            isExpanded: true
        )
    ]

    lazy var collectionView: UICollectionView = {
        let collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: createCollectionViewLayout())
        collectionView.register(Cell.self, forCellWithReuseIdentifier: Cell.reuseIdentifier)
        collectionView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        collectionView.contentInset.top = 44
        collectionView.backgroundColor = .white
        collectionView.delegate = self
        return collectionView
    }()

    lazy var dataSource = UICollectionViewDiffableDataSource<Int, Item>(collectionView: collectionView) { collectionView, indexPath, itemIdentifier in
        guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: Cell.reuseIdentifier, for: indexPath) as? Cell else { fatalError() }
        cell.isExpanded = itemIdentifier.isExpanded
        cell.label.text = itemIdentifier.text
        return cell
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        dataSource.supplementaryViewProvider = { (collectionView, kind, indexPath) -> UICollectionReusableView? in
            guard let view = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: Header.elementKind, for: indexPath) as? Header else { fatalError() }
            view.label.text = "Test"
            return view
        }
        view.addSubview(collectionView)
        collectionView.register(Header.self, forSupplementaryViewOfKind: Header.elementKind, withReuseIdentifier: Header.elementKind)
        updateSnapshot()
    }

    private func createCollectionViewLayout() -> UICollectionViewCompositionalLayout {
        let layoutSize = NSCollectionLayoutSize.init(
            widthDimension: .fractionalWidth(1.0),
            heightDimension: .estimated(200)
        )

        let section = NSCollectionLayoutSection(group:
            .vertical(
                layoutSize: layoutSize,
                subitems: [.init(layoutSize: layoutSize)]
            )
        )
        
        let header = NSCollectionLayoutBoundarySupplementaryItem(layoutSize: .init(widthDimension: .fractionalWidth(1), heightDimension: .estimated(20)), elementKind: Header.elementKind, alignment: .top)
        section.boundarySupplementaryItems = [header]
        section.contentInsets = .init(top: 0, leading: 16, bottom: 0, trailing: 16)
        section.interGroupSpacing = 20

        return .init(section: section)
    }

    private func updateSnapshot() {
        var snapshot = NSDiffableDataSourceSnapshot<Int, Item>()
        snapshot.appendSections([0])
        snapshot.appendItems(items)
        dataSource.apply(snapshot, animatingDifferences: true)
    }
}

// MARK: - UICollectionViewDelegate -

extension ViewController: UICollectionViewDelegate {
    public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        guard let itemIdentifier = dataSource.itemIdentifier(for: indexPath) else { return }
        items[indexPath.row] = .init(text: itemIdentifier.text, isExpanded: !itemIdentifier.isExpanded)
        updateSnapshot()
    }
}

感谢@JWK


这种行为似乎出乎意料,尽管我相信它的发生只是因为整个部分都用动画更新了apply(_:animatingDifferences:completion:)。您可以尝试以下几种解决方法:

  1. Set animatingDifferences to false打电话时apply(_:animatingDifferences:completion:)。如果您想要动画,则不太理想。
  2. 添加另一个部分而不是使用boundarySupplementaryItems。不扩展的部分不应影响视觉效果。您可能需要引入另一个单元并使用UICollectionViewCompositionalLayout's init(sectionProvider:)为此(提供正确的NSCollectionLayoutSection对于每个部分)。
  3. 如果您使用的是 iOS 14+,我认为您可以通过设置来免费获得所需的行为UICollectionViewListCell's accessories财产给UICellAccessory.OutlineDisclosureOptions(style: .header)。有一个示例项目以及其他有用的示例here https://developer.apple.com/documentation/uikit/views_and_controls/collection_views/implementing_modern_collection_views.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

diffable 数据源节标题在更新期间闪烁 的相关文章

  • 在一个命令中选择或插入一行

    我使用的是 PostgreSQL 9 0 我有一个表 其中只有一个人工键 自动递增序列 和另一个唯一键 是的 这个表是有原因的 我想通过另一个键查找 ID 或者如果它不存在 则插入它 SELECT id FROM mytable WHERE
  • 如何限制单元测试的最大运行时间?

    我目前正在运行一些单元测试 这些测试可能需要很长时间才能失败或无限期地运行 在成功的测试运行中 它们总是会在一定的时间内完成 是否可以创建一个 pytest 单元测试 如果在一定时间内未完成 该测试就会失败 您可以安装 pytest tim
  • Mac 无法安装 Tensorflow

    我检查了我的 pip3 和 python3 版本 tensorflow MacBook Pro de Hector 2 tensorflow hectoresteban pip3 V pip 10 0 1 from Users hector
  • 从 Java 程序中获取局部变量的名称和类型

    这是我正在尝试的代码 JavaCompiler compilerA ToolProvider getSystemJavaCompiler int resultA compilerA run null null null Users a Do
  • 将我的应用程序添加到“添加快捷方式”列表,以便在主屏幕上有快捷方式

    如您所知 当您长按主屏幕时 手机会显示列表菜单 您可以添加快捷方式 小部件 文件夹等 我希望我的应用程序位于快捷方式列表中 我怎样才能做到这一点 快捷方式自 API 级别 1 起就已存在 并且也可由 3rd 方应用程序使用 要将活动添加到快
  • 不允许在 MS Access 中创建或更改记录

    我已经阅读了有关上述问题的大量帖子 但没有一个答案能够解决问题 我的问题是两个表使用 ID 字段 也是主键 相互链接 以一对一的关系 当我尝试在主表中输入记录时 不知道 Access 是否知道这是主表 出现以下错误 You cannot a
  • JFrame.repaint() 和 JPanel.repaint() 之间的区别

    谁能解释一下两者之间的区别JPanel repaint 方法和JFrame repaint 方法 我想两者都调用paintComponent JPanel 中的方法 请澄清 谢谢 Calling repaint 在任何组件上都会向重绘管理器
  • 获取 Flask 中没有端口的请求主机名

    我刚刚设法使用 Flask 获取我的应用程序服务器主机名request host and request url root 但这两个字段都返回请求主机名及其端口 我想使用仅返回请求主机名的字段 方法 而无需进行字符串替换 如果有 没有 We
  • 使用捕获信号和噪声的 PSD 计算 SNR

    I have captured both a transmitted signal and when there is no transmission i e noise only I would like to calculate the
  • Xamarin Macintosh 客户 URL 协议句柄传递的参数

    我编写了一个处理自定义协议的 Macintosh 应用程序
  • CSS 链接图像带有下划线(“a”显示设置为阻止)

    我有一个菜单 我希望每个单独的项目中文本周围的所有空间都能将用户带到指定的页面 我在网上查了一下 发现最好的解决方案是将 a 显示设置为阻止 如下 a display block height 100 text decoration und
  • 让 MSBuild 将文件输出到日志?

    我有一个输出到文件的程序 我正在从 MSBuild 项目运行它 我希望将此输出写入 StdOut 以便我们的构建代理 TeamCity 可以获取它 如何让 MSBuild 将文件内容转储到输出 DOS命令type http www comp
  • 从 google play 中提取统计信息

    我正在建立一些统计数据 并希望获得来自 google play 应用程序商店 的统计数据 最受欢迎 下载量 价格等信息 有谁知道是否有这个 API 或者我必须自己抓取它 有一个名为 android market api 的项目http co
  • PHP SFTP 简单文件上传

    我正在使用 phpseclib SFTP 类 并尝试上传这样的文件 sftp new Net SFTP mydomain com if sftp gt login user password exit Login Failed sftp g
  • java中的“main”可以返回字符串吗?

    java中的public static void main String args 是否有可能返回String代替void 如果是 怎么办 public static String main String args 代替 public st
  • 定义Python类时,如何在其中设置随机变量?

    假设我有一个名为Person 其中只有该人的姓名和性别 性别应从男性和女性中随机选择 为此 我导入random randint 功能 根据随机int确定随机性别 import random class Person alias random
  • Json.net 将数字属性序列化为字符串

    我正在使用 JsonConvert SerializeObject 序列化模型对象 服务器期望所有字段都是字符串 我的模型对象具有数字属性和字符串属性 我无法向模型对象添加属性 有没有办法将所有属性值序列化为字符串 我必须只支持序列化 而不
  • 如何将 Three.js 代码实施到 Android 移动应用程序中?

    我用 HTML CSS 和 JS 编写了 Three js 场景的代码 显示 3D 头部模型及其上的标记 它适用于我的 Angular 项目 我还可以通过将 HTML 代码添加到 Web 视图中 使其在适用于 Android 和 iOS 的
  • 在 Azure Active Directory (AAD) 中注册微服务以确保安全

    我在服务结构集群中部署了一个服务结构应用程序 无状态和有状态 我正在尝试在应用程序中实现安全性 应用程序使用 Active Directory 身份验证库 ADAL 通过 OAuth 2 0 客户端凭据流从 Azure AD 获取令牌 其中
  • 如何在流体宽度表中使用省略号而不使每列大小相同?

    假设我的表中的列是id name description and phone The description列的长度为 1 255 个字符 但 id 最多只有 3 个字符 我希望列的大小适当 而不是每列的大小相同 我想要descriptio

随机推荐

  • Jetty 9 + Java > 8u74 总是在 Linux 上分配最大(-Xmx)内存?

    如果我使用 Xmx512m 在 Linux 上使用 jre 8u74 启动 Java 应用程序 则不会立即分配内存 如果 Java 需要内存 则会分配内存 因此 如果没有必要 它可以保持在 512 MB 限制以下 这是我所期望的 在 Jav
  • PHP 除法浮点值问题

    当我尝试获取余数时 它给出了无效值 我试图获得两位小数的余数 我得到 3 4694469519536E 18 我的价值观是 x 0 1 y 0 005 我尝试了以下方法 echo ed fmod 0 1 0 005 OutPut 3 469
  • Laravel 5 注销特定用户

    在我的 laravel 5 应用程序中 有一个功能允许具有管理员角色的用户重置非管理员的任何人的密码 但这不会强制该人注销并再次登录 更改密码后如何强制用户注销 我没有对用于验证用户身份或任何内容的中间件进行任何更改 我不知道它是否有效 但
  • Xcode 11 PDF 图像资源“保留矢量数据”在 SwiftUI 中不起作用?

    我正在尝试在 Xcode 11 中使用 SwiftUI 的应用程序中使用 Single Scale 来使用基于矢量的 PDF 图像 但当我放大图像尺寸时 图像总是看起来模糊 我在 Xcode 11 的 UIKit 中没有遇到任何问题 我创建
  • 如何列出Resources文件夹中的所有文件(java/scala)

    我正在编写一个函数 需要访问资源中的文件夹 并循环遍历所有文件名 如果这些文件符合条件 则加载这些文件 new File getClass getResource images sprites getPath listFiles 返回空指针
  • 哪个 PHP 5 版本最常用?

    当我开发将在不同配置的客户端 Web 服务 通常使用共享托管 上使用的应用程序时 我应该假设大多数 Web 服务器都具有哪个 PHP 5 版本 例如 5 2 x 5 3 x 等 在所有使用 PHP 版本 5 的网站中 有 84 9 使用版本
  • 无法加载文件 /../firebase.js ... 。编码不是UTF-8

    描述一下您的环境 操作系统版本 mac os Firebase SDK 版本 4 8 1 Firebase 产品 数据库 描述问题 当我尝试将 firebase js 添加到 chrome 扩展时 浏览器显示错误 无法加载文件 fireba
  • 更新查询时 ios 中出现“数据库锁定”错误

    我正在使用下面的代码更新查询 using sqlite 但我越来越 database is locked error 我尝试搜索一些 SO 链接 建议关闭数据库 但我再次执行此操作时遇到相同的错误 我已经提到过代码中出现错误的地方 cons
  • phoenix 框架 - 新套接字处的参数无效 - windows

    我无法运行新的 Phoenix 应用程序 这是我收到的错误 我不确定原因是什么 我尝试更改端口 但这并没有改变行为 另外 我似乎能够正确运行节点 Compiled web views error view ex Compiled web c
  • 在Python中从CSV文件中获取随机行并找到相应的单词,就像测验一样

    抱歉标题含糊不清 想不出更好的表达方式 我有一个包含德语 英语单词的 CSV 文件 如下所示 Ja Yes Nein No Katze Cat 我希望我的 python 脚本从 CSV 文件中打印一个随机的德语单词 并要求他们输入英语单词
  • 如何检查我的 create-nuxt-app 版本并升级?

    背景 以前 运行yarn create nuxt app myApp 会安装Nuxt v2 4 0 但今天我注意到您降级到Nuxt v2 0 0 我没有改变开发环境 所以我无法理解这种行为 当我发现这个问题时 我做了一些搜索并在其他地方抱怨
  • 使用 Subversion 标签部署到开发/登台/测试服务器

    Subversion 标签是发布到开发或登台服务器的好方法吗 我设想这个 当主干变得稳定时 就会使用该版本创建一个标签 开发服务器利用 Subversion 切换到该标签 更新到文件的最新版本 删除不再需要的文件等 我设想的服务器帐户也只能
  • RVM 要求错误

    我安装了 OS X Mavericks 并且正在尝试运行rvm requirements在终端中 它给了我这个错误 Installing required packages autoconf automake libtool pkgconf
  • Android:我的应用程序太大并给出“无法执行 dex:方法 ID 不在 [0, 0xffff]: 65536”?

    我正在尝试将我的应用程序与 Box Dropbox 和 Google Drive 集成 所有这 3 项服务都需要许多第 3 方 jar 此外 我的应用程序已经需要一些第三方 jar 现在 当我尝试从 Eclipse 运行我的应用程序时 出现
  • 从另一台服务器读取 Node.js 中的大文件

    我有两台相互通信的服务器 Server1 向 Server2 请求文件的部分内容 并将收到的数据存储到一个文件中 Server2 应该接收每个请求并创建一个流管道传输数据 假设服务器2中存储的文件 目录 如下 bigfile gz bigf
  • 线程和 fork()。我该如何处理呢? [复制]

    这个问题在这里已经有答案了 可能的重复 多线程程序中的fork https stackoverflow com questions 1235516 fork in multi threaded program 如果我有一个使用 fork 的
  • jQuery可排序发布数据,但没有数据

    谁能告诉我我在这里缺少什么 我的数据似乎总是空的 我做错了什么 document ready function nav sortable connectWith nav axis y update function event ui var
  • 英特尔 Pin 与 C++14

    问题 我有一些关于在 C 14 或其他 C 版本中使用英特尔 Pin 的问题 使用较新版本从较旧的 C 编译代码很少会出现任何问题 但由于 Intel Pin 是操作指令级别的 如果我使用 C 11 或 C 14 编译它 是否会出现任何不良
  • HTML标题属性样式[重复]

    这个问题在这里已经有答案了 如何在不使用 javascript 或 CSS 的情况下更改以下标记中标题属性的样式 因为我将 HTML 插入到原本无法编辑的文档中的特定位置 span title This is information Thi
  • diffable 数据源节标题在更新期间闪烁

    我目前面临的问题是 当将新快照应用于当前数据源时 页眉 页脚和装饰视图不是集合视图子视图的一部分 这可以被视为奇怪的闪烁 以前有人遇到过这个问题吗 我通过以下方式更新数据源 var snapshot NSDiffableDataSource