Reputation: 9586
I have a UICollectionView
that I placed in a custom UIViewController
via Storyboard and pinned its leading/trailing/top/bottom space to its superview.
Then I have a custom UICollectionViewController
subclass that should use the collection view. So in the superview's UIViewController
(PrimaryViewController) I have an outlet to the collection view and I instantiate my custom UICollectionViewController
. I assign it the collection view and I assign the custom UICollectionViewController as delegate and dataSource for the collection view.
But when I run this, the collection view doesn't appear on the screen. It is obvious that the viewDidLoad()
doesn't get called in the custom UICollectionViewController
class so either I'm missing a key part or I'm approaching this the wrong way.
Can somebody tell me how to construct the connection between the collection view (which is placed via Storyboard) and the custom UICollectionViewController
class (which is code only) in a way that makes this work properly?
Here's my (simplified) code so far ...
class PrimaryViewController : UIViewController {
@IBOutlet private weak var _collectionView:UICollectionView!
private var _collectionViewCtrl:CustomCollectionViewController!
override func viewDidLoad() {
super.viewDidLoad()
_collectionViewCtrl = CustomCollectionViewController(collectionView: _collectionView)
}
}
class CustomCollectionViewController : UICollectionViewController {
init(collectionView:UICollectionView) {
super.init(nibName: nil, bundle: nil)
self.collectionView = collectionView
self.collectionView.delegate = self
self.collectionView.dataSource = self
}
required init(coder aDecoder:NSCoder) {
super.init(coder: aDecoder)
}
override func viewDidLoad() {
super.viewDidLoad()
}
}
Upvotes: 0
Views: 2566
Reputation: 3789
In IB or your Storyboard, you can use a container view and embed your custom collection view controller inside. This gives you the ability to manipulate each view controller in it's own context, because they each have their own nib
, and will handle instantiating your collection view controller auto-magically.
Your PrimaryViewController
can look like this:
class PrimaryViewController : UIViewController {
@IBOutlet private weak _collectionView: UIView
private var _collectionViewController: CustomCollectionViewController! {
// ???: You can also iterate through child view controllers looking for a class match if you embed other controllers.
return self.childViewControllers[0] as CustomCollectionViewController!
}
override func viewDidLoad() {
super.viewDidLoad()
}
}
Which will also call viewDidLoad()
on your CustomCollectionViewController
. You can hide and show the view through the _collectionView
property, or directly manipulate it through _collectionViewController
.
The pain comes from any logic that may be the appearance logic (viewWillAppear(_: Bool)
, viewWillDisappear(_: Bool)
, etc) because you'll have to trigger those yourself.
Your storyboard should look something like this (My container view is hidden):
Upvotes: 2
Reputation: 34829
Note that the object that acts as the delegate/datasource for a UICollectionView
does not have to be derived from UICollectionViewController
. In fact, it shouldn't be unless you dragged out a UICollectionViewController in storyboard.
The datasource/delegate class should be derived from NSObject
@interface CustomCollectionViewSupervisor : NSObject <UICollectionViewDataSource, UICollectionViewDelegate>
and must implement the datasource/delegate methods, including but not necessarily limited to
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
Upvotes: 1