Mac 上 CollectionView 单元格中的 UITextView 使 CPU 峰值

Ric*_*oon 5 macos uitextview uicollectionview

我有一个简单的 UIKit 应用程序,它有一个UITextView一个UICollectionViewCell. 该应用程序专为 iOS/iPadOS 设计,在这些平台上运行良好。然而,当我在 Mac(专为 iPad 设计)上运行时,一旦我开始滚动 CollectionView,CPU 使用率就会飙升至约 85%,并无限期地保持在该水平。降低 cpu 的唯一方法是在应用程序窗口之外单击,但一旦再次到达前台,cpu 使用率就会立即跳回原来位置。我也尝试过在 Mac 上以 Catalyst 模式运行,但 CPU 使用率稍低(约 45%)时也会出现同样的问题。

\n

此外,调试器不断地吐出[API] cannot add handler to 3 from 3 - dropping

\n

有人对此有解释或解决方案吗?

\n

I\xe2\x80\x99m 在 macOS Ventura 13.0 (22A380) 上使用 Xcode 版本 14.1 (14B47b)。

\n
class ViewController: UIViewController {\n    var dataSource: UICollectionViewDiffableDataSource<Section, String>! = nil\n    var collectionView: UICollectionView! = nil\n    var items = Array(0...100).map{"Item \\($0)"}\n    \n    enum Section: String {\n        case main\n    }\n    \n    override func viewDidLoad() {\n        super.viewDidLoad()\n        navigationItem.title = "List"\n        configureCollectionView()\n        configureDataSource()\n        applyInitialSnapshot()\n    }\n    \n    private func createLayout() -> UICollectionViewLayout {\n        return UICollectionViewCompositionalLayout { sectionIndex, layoutEnvironment in\n            let size = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .estimated(100))\n            let item = NSCollectionLayoutItem(layoutSize: size)\n            let group = NSCollectionLayoutGroup.horizontal(layoutSize: size, subitems: [item])\n            \n            return NSCollectionLayoutSection(group: group)\n        }\n    }\n    \n    private func configureCollectionView() {\n        collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: createLayout())\n        collectionView.autoresizingMask = [.flexibleWidth, .flexibleHeight]\n        collectionView.backgroundColor = .systemBackground\n        view.addSubview(collectionView)\n    }\n    \n    private func configureDataSource() {\n        let cellRegistration = UICollectionView.CellRegistration<TestCell, String> { (cell, indexPath, item) in\n            cell.configure(title: item, row: indexPath.item)\n        }\n        \n        dataSource = UICollectionViewDiffableDataSource<Section, String>(collectionView: collectionView) {\n            (collectionView, indexPath, identifier) -> UICollectionViewCell? in\n            \n            return collectionView.dequeueConfiguredReusableCell(using: cellRegistration, for: indexPath, item: identifier)\n        }\n    }\n    \n    private func applyInitialSnapshot() {\n        var snapshot = NSDiffableDataSourceSnapshot<Section, String>()\n        snapshot.appendSections([.main])\n        snapshot.appendItems(items)\n        \n        dataSource.apply(snapshot, animatingDifferences: false)\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n
class TestCell: UICollectionViewCell {\n    private let annotationsTextView = UITextView()\n\n    override init(frame: CGRect) {\n        super.init(frame: frame)\n        addViews()\n    }\n    \n    required init?(coder: NSCoder) {\n        fatalError("init(coder:) has not been implemented")\n    }\n    \n    func configure(title: String, row: Int) {\n        annotationsTextView.attributedText = .init(string: "Row: \\(row) Item: \\(title)", attributes: [.font: UIFont.preferredFont(forTextStyle: .title1)])\n    }\n    \n    private func addViews() {\n        annotationsTextView.isScrollEnabled = false\n        annotationsTextView.isEditable = false\n        annotationsTextView.translatesAutoresizingMaskIntoConstraints = false\n        \n        contentView.addSubview(annotationsTextView)\n        \n        NSLayoutConstraint.activate([\n            annotationsTextView.topAnchor.constraint(equalTo: contentView.topAnchor),\n            annotationsTextView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),\n            annotationsTextView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),\n            annotationsTextView.trailingAnchor.constraint(equalTo:  contentView.trailingAnchor),\n        ])\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

Jef*_*ton 0

每当视图层次结构中的任何位置有一个 UITextView 且 isSelectable 或 isEditable 设置为 true 时,我都会在 Ventura 中遇到这种确切的行为,但仅限于 UITextView 不是第一响应者时。无论 UITextView 是可见还是隐藏,都会发生这种情况。

可以通过以下任一方法来防止 CPU 使用率过高:

  • 从视图层次结构中删除 UITextView。
  • 将 isSelectable 和 isEditable 设置为 false。
  • 使 UITextView 成为第一响应者。

我仍在调查,如果发现更多信息,我会在这里更新。我们都应该向苹果报告这个问题,因为我想他们需要在系统级别修复这个问题。

2022年12月1日:更新

从 macOS 13.1 beta 4 (22C5059b) 开始,此问题似乎已得到解决。哈利路亚!