Reputation: 89
I've been struggling with this for hours as I'm relatively new to XCode and Swift.
I have a CollectionView
in my storyboard and want to link its data source and delegate methods to a separate class other than my ViewController
but it isn't working.
Can anyone help?
override func viewDidLoad() {
super.viewDidLoad()
//
self.card.center = CGPoint(x: self.view.center.x, y: self.view.center.y)
self.card.layer.cornerRadius = 5
self.card.layer.shadowOpacity = 0.1
//
self.card2.center = CGPoint(x: self.view.center.x, y: self.view.center.y)
self.card2.layer.cornerRadius = 5
self.card2.layer.shadowOpacity = 0.1
//
self.view.bringSubview(toFront: self.card)
// HERE IS THE LINK
setDS()
collectionView.reloadData()
// ----------------------
}
private func setDS() {
let dataSourceAndDelegate = CollectionViewController()
collectionView.dataSource = dataSourceAndDelegate
collectionView.delegate = dataSourceAndDelegate
}
import UIKit
private let reuseIdentifier = "Cell"
class CollectionViewController: UICollectionViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.red
print("View did load")
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Register cell classes
self.collectionView!.register(UICollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
// MARK: UICollectionViewDataSource
override func numberOfSections(in collectionView: UICollectionView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of items
return 3
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath)
// Configure the cell
cell.backgroundColor = UIColor.blue
return cell
}
// MARK: UICollectionViewDelegate
// Uncomment this method to specify if the specified item should be highlighted during tracking
override func collectionView(_ collectionView: UICollectionView, shouldHighlightItemAt indexPath: IndexPath) -> Bool {
return true
}
// Uncomment this method to specify if the specified item should be selected
override func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool {
return true
}
// Uncomment these methods to specify if an action menu should be displayed for the specified item, and react to actions performed on the item
override func collectionView(_ collectionView: UICollectionView, shouldShowMenuForItemAt indexPath: IndexPath) -> Bool {
return false
}
override func collectionView(_ collectionView: UICollectionView, canPerformAction action: Selector, forItemAt indexPath: IndexPath, withSender sender: Any?) -> Bool {
return false
}
override func collectionView(_ collectionView: UICollectionView, performAction action: Selector, forItemAt indexPath: IndexPath, withSender sender: Any?) {
}
}
Upvotes: 2
Views: 4057
Reputation: 9484
Don't use subclass of UICollectionViewController
as datasource and delegate of your custom collectionview.
Instead use simple NSObject class. That way you would need to implement only the datasource and delegate methods and dont have to worry about UIViewcontroller's view methods(you dont need them anyway).
But even if you provide object of UICollectionViewController
it should work. It is not working because you have not retained the object in your ViewController
class and it is getting autoreleased. UICollectionView does not retain delgeate and datasource to prevent retain cycles.
let dataSourceAndDelegate = CollectionViewController()
Make dataSourceAndDelegate
a stored property.
Also, you would need to register your cell inside ViewController class (because it has the collection view you are working with). Remember collectionView
property inside UICollectionViewController
is not same as your collectionView in ViewController
. It is a stored property because UICollectionViewController
comes with a colectionview.
private let reuseIdentifier = "Cell"
class ViewController: UIViewController {
let dataSourceAndDelegate = CollectionViewController()
@IBOutlet var collectionView:UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
self.setDS()
collectionView.reloadData()
}
private func setDS() {
// Register cell classes
self.collectionView!.register(UICollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)
collectionView.dataSource = dataSourceAndDelegate
collectionView.delegate = dataSourceAndDelegate
}
}
Upvotes: 2