Use CollectionView methods from another swift file

2019-08-27 10:49发布

问题:

I'd like to use a CollectionView methods from another swift file instead of it's ViewController for some reason.

I have this in my ViewController:

@IBOutlet weak var collectionView: UICollectionView!
var broadcastColletionView = BroadcastCollectionView()

override func viewDidLoad() {
super.viewDidLoad()
broadcastColletionView = BroadcastCollectionView(eventItems: eventItems,collectionView: collectionView, broadastObject: broadastObject)
collectionView.dataSource = broadcastColletionView
collectionView.delegate = broadcastColletionView
}

And I have BroadcastCollectionView.swift which contains the CollectionView delegate methods:

class BroadcastCollectionView: NSObject,UICollectionViewDelegate, UICollectionViewDataSource {

var eventItems = [Eventtype]()
var alreadyChecked: Bool = false
var cellHistory: IndexPath = []
var collectionView: UICollectionView! 
var broadastObject = Broadcast()

init(eventItems: [Eventtype],collectionView: UICollectionView, 
broadastObject: Broadcast) {
self.eventItems = eventItems
self.collectionView = collectionView
self.broadastObject = broadastObject
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return eventItems.count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "brCollectionView", for: indexPath) as! BroadcastCollectionViewCell

    self.collectionView = collectionView

    cell.eventImage.image = eventItems[indexPath.row].image
    cell.eventType = eventItems[indexPath.row]
    let tap = UITapGestureRecognizer(target: self, action: #selector(collectionViewTapped))
    tap.numberOfTapsRequired = 1

    cell.addGestureRecognizer(tap)

    return cell

}

@objc func collectionViewTapped(sender: UITapGestureRecognizer) {
    if let indexPath = self.collectionView?.indexPathForItem(at: sender.location(in: self.collectionView)) {

        let cell : BroadcastCollectionViewCell = collectionView.cellForItem(at: indexPath)! as! BroadcastCollectionViewCell
        print("item index")
    } else {
        print("collection view was tapped")
    }
}

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    print("selected row is",indexPath.row)
}

I don't really understand why the delegate methods not called if I setted the collectionView.delegate and dataSource to the BroadcastCollactionViewclass. Please don't make me explain why would I like to separate this CollectionView it's not part of the question.

回答1:

Apart from the issue of not working in your case which could be due to not configuring the collection view properly which can be resolved using the answers you got above from other users,

There is an approach for your question of "Use CollectionView methods from another swift file"
You can make use of the concept called "extension", I will explain you how.

  1. Create a new class for handling the collection view methods as follows,
class MyDataSource: NSObject {
    var eventItems: Array<Any>?

    init(events: Array<Any>?) {
        self.eventItems = events
    }
}

extension MyDataSource: UITableViewDataSource, UITableViewDelegate {

    // MARK: - Table view data source methods

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "CellIdentifier")

        return cell
    }

    // Add additional data source methods & delegate methods as per your need

    // MARK: - Table view delegate methods

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        // Perform your action
        // Use delegate methods(protocols) to do your actions from the viewController class
    }

}
  1. And in the viewController file assign the datasource & delegate method for collection view as follows,

class ViewController: UIViewController { var datasource: MyDataSource?

override func viewDidLoad() {
    super.viewDidLoad()

    // Initialize datasource & delegate for collectionView with the extension datasource
    datasource = MyDataSource(events: EVENTITEMS_ARRAY)
    collectionView?.dataSource = datasource
    collectionView?.delegate = datasource
    } 
}

NOTE

  1. Update the data types & collection view properties like cell identifier as per your need.


回答2:

After setting datasource and delegate for the collection view in viewDidLoad() method, reload the collection view:

 collectionView.reloadData()


回答3:

This another class that you created is called CustomDataSource you can find a tutorial here

Try calling collectionView.reloadData() after setting the dataSource and delegate.

and Make sure eventItems is not empty.

Hope it Helps!