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
ViewController
toUICollectionViewController
, 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.