为什么我的 UICollectionView 大纲不起作用?
Why doesn't my UICollectionView outline work?
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)
}
}
编辑 已在 Xcode 12 beta 4 中修复。原始示例现在可以正常工作。
你的视图控制器没问题。你做的一切都正确。
问题出在场景委托中的这一行:
self.window!.rootViewController = CollectionViewController()
由于完全晦涩的原因 — Apple 未能在任何地方提及此 — 此功能 仅在导航控制器界面中有效。 将该行更改为:
self.window!.rootViewController = UINavigationController(rootViewController: CollectionViewController())
大纲现在 spring 栩栩如生。
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)
}
}
编辑 已在 Xcode 12 beta 4 中修复。原始示例现在可以正常工作。
你的视图控制器没问题。你做的一切都正确。
问题出在场景委托中的这一行:
self.window!.rootViewController = CollectionViewController()
由于完全晦涩的原因 — Apple 未能在任何地方提及此 — 此功能 仅在导航控制器界面中有效。 将该行更改为:
self.window!.rootViewController = UINavigationController(rootViewController: CollectionViewController())
大纲现在 spring 栩栩如生。