I'm making a UIKit app with no storyboard.
This is my scene delegate:
import UIKit
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
let window = UIWindow(windowScene: windowScene)
window.makeKeyAndVisible()
window.rootViewController = UINavigationController(rootViewController: ViewController())
self.window = window
}
}
I've noticed that if I subclass ViewController to UICollectionViewController, the app crashes with message "Thread 1: "UICollectionView must be initialized with a non-nil layout parameter"":
import UIKit
class ViewController: UICollectionViewController {
}
It looks like I necessarily need to override the initializer:
import UIKit
class ViewController: UICollectionViewController {
init() {
super.init(collectionViewLayout: .init())
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
I would indeed like to pass the final collection view layout in super.init(collectionViewLayout:), but defining the trailing actions before that isn't possible since self hasn't been initialized yet.
So this is what I'm stuck with:
import UIKit
class ViewController: UICollectionViewController {
init() {
super.init(collectionViewLayout: .init())
var configuration = UICollectionLayoutListConfiguration(appearance: .insetGrouped)
var layout = UICollectionViewCompositionalLayout.list(using: configuration)
configuration.trailingSwipeActionsConfigurationProvider = { [weak self] indexPath -> UISwipeActionsConfiguration? in
// access a property of self
return .init(actions: [.init(style: .destructive, title: "Hello", handler: { _,_,_ in print("Handled") })])
}
layout = UICollectionViewCompositionalLayout.list(using: configuration)
collectionView.collectionViewLayout = layout
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Is this all valid?
I've noticed that if I subclass
ViewControllertoUICollectionViewController, the app crashes with message "Thread 1: "UICollectionView must be initialized with a non-nil layout parameter"":
My best guess is that the view controller in your storyboard wasn't configured correctly.
When you add the view controller to your storyboard, try to add a Collection View Controller, and not a View Controller. That should give you a configured collection view controller. Then, in the storyboard, you can set the controller's class to your UICollectionViewController subclass, and initialize the layout in your controller's viewDidLoad.
In the case where you need to create your UICollectionViewController subclass programmatically (and not by loading from a storyboard), calling super.init with a dummy layout and setting up the layout after that, as shown in your code snippet, looks good to me.
Best,
——
Ziqiao Chen
Worldwide Developer Relations.