为啥我的 UICollectionView 大纲不起作用?

Posted

技术标签:

【中文标题】为啥我的 UICollectionView 大纲不起作用?【英文标题】:Why doesn't my UICollectionView outline work?为什么我的 UICollectionView 大纲不起作用? 【发布时间】:2020-07-27 21:10:52 【问题描述】:

ios 14 中的新功能,您可以使用 UICollectionViewCompositionalLayout.list 和 NSDiffableDataSourceSectionSnapshot 来制作自动 outline 类型的列表。 Apple 在 WWDC 视频中展示了这一点,他们有一个名为 Modern Collection Views 的示例代码项目也展示了这一点。

但是当这样做时,它就不起作用了。我看到了根项目,但是当我点击它时,它并没有展开。为什么不呢?

我有这个问题即使我将 Apple 的代码复制并粘贴到我自己的项目中。我不明白。同样的代码适用于 Apple 的项目,但不适用于我的项目。

这是一个完整的可重现示例。这是项目的整个代码。告诉我它有什么问题!

应用代理

import UIKit

@main
class AppDelegate: UIResponder, UIApplicationDelegate 
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool 
        return true
    

场景代理

import UIKit

class SceneDelegate: UIResponder, UIWindowSceneDelegate 
    var window: UIWindow?
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) 
        let scene = scene as! UIWindowScene
        self.window = UIWindow(windowScene: scene)
        self.window!.rootViewController = CollectionViewController()
        self.window!.makeKeyAndVisible()
    

视图控制器

import UIKit

class CollectionViewController: UICollectionViewController 
    init() 
        let config = UICollectionLayoutListConfiguration(appearance: .plain)
        let layout = UICollectionViewCompositionalLayout.list(using: config)
        super.init(collectionViewLayout: layout)
    
    required init?(coder: NSCoder) 
        super.init(coder: coder)
    
    private let cellId = "Cell"
    
    var dataSource: UICollectionViewDiffableDataSource<String, String>! = nil
    
    override func viewDidLoad() 
        super.viewDidLoad()
        self.collectionView.register(UICollectionViewListCell.self, forCellWithReuseIdentifier: self.cellId)
        
        let ds = UICollectionViewDiffableDataSource<String, String>(collectionView:self.collectionView)  cv, ip, s in
            let cell = cv.dequeueReusableCell(withReuseIdentifier: self.cellId, for: ip) as! UICollectionViewListCell
            var contentConfig = cell.defaultContentConfiguration()
            contentConfig.text = s
            if ip.item == 0 
                let opts = UICellAccessory.OutlineDisclosureOptions(style: .header)
                cell.accessories = [.outlineDisclosure(options: opts)]
             else 
                cell.accessories = []
            
            cell.contentConfiguration = contentConfig
            return cell
        
        self.dataSource = ds
        
        var snap = NSDiffableDataSourceSectionSnapshot<String>()
        snap.append(["Pep"], to: nil)
        snap.append(["Manny", "Moe", "Jack"], to: "Pep")
        self.dataSource.apply(snap, to: "Dummy", animatingDifferences: false, completion: nil)
    

【问题讨论】:

【参考方案1】:

编辑已在 Xcode 12 beta 4 中修复。原始示例现在可以正常工作。

您的视图控制器很好。你做的一切都是正确的。

问题是场景委托中的这一行:

self.window!.rootViewController = CollectionViewController()

出于完全不明确的原因——Apple 没有在任何地方提及这一点——此功能仅在导航控制器界面中有效。将该行更改为:

self.window!.rootViewController = UINavigationController(rootViewController: CollectionViewController())

轮廓现在将栩栩如生。

【讨论】:

仅供参考,轮廓与导航控制器无关;如果您发现在某些情况下无法展开/折叠,这只是 iOS 14 测试版中的一个错误。 @smileyborg F Y I 浪费我六个小时的时间没有什么“只是”一个错误。我一发现就向苹果报告了这个问题,所以如果你在团队中,请修复这个错误。如果您不在团队中,我不明白您是如何知道轮廓与导航控制器无关的;事实上,我的例子无可争辩地证明了它们确实如此,无论这看起来多么不可能。 请在今天发布的最新 iOS 14 beta 4 中试一试。

以上是关于为啥我的 UICollectionView 大纲不起作用?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的 uicollectionview 不随底层 uiscrollview 一起移动?

为啥我的 UICollectionView 单元格在我的 swift ios 应用程序中不可点击?

为啥我不能从我的 UICollectionView 中删除图像?

为啥 UICollectionView 不滚动其中的 UIButtons?

为啥我的 UICollectionView 支持方法仅在我的 ViewController 设置为初始视图控制器时调用?

为啥我的 UITableView 需要在场景大纲中的 UIButton 下面