How can I add multiple collection views in a UIViewController in Swift?

前端 未结 5 1388
栀梦
栀梦 2020-12-07 08:35

I tried many days to realise this: \"enter

I want to add in my UIViewController two di

相关标签:
5条回答
  • 2020-12-07 08:57

    This is possible, you just need to add each UICollectionView as a subview, and set the delegate and dataSource to your UIViewController.

    Here's a quick example. Assuming you have one UICollectionView working, you should be able to adapt this code to your own uses to add a second fairly easily:

    let collectionViewA = UICollectionView()
    let collectionViewB = UICollectionView()
    let collectionViewAIdentifier = "CollectionViewACell"
    let collectionViewBIdentifier = "CollectionViewBCell"
    
    override func viewDidLoad() {
        // Initialize the collection views, set the desired frames
        collectionViewA.delegate = self
        collectionViewB.delegate = self
    
        collectionViewA.dataSource = self
        collectionViewB.dataSource = self
    
        self.view.addSubview(collectionViewA)
        self.view.addSubview(collectionViewB)
    }
    

    In the cellForItemAtIndexPath delegate function:

    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        if collectionView == self.collectionViewA {
            let cellA = collectionView.dequeueReusableCellWithReuseIdentifier(collectionViewAIdentifier) as UICollectionViewCell
    
            // Set up cell
            return cellA
        }
    
        else {
            let cellB = collectionView.dequeueReusableCellWithReuseIdentifier(collectionViewBIdentifier) as UICollectionViewCell
    
            // ...Set up cell
    
            return cellB
        }
    }
    

    In the numberOfItemsInSection function:

    func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        if collectionView == self.collectionViewA {
            return 0 // Replace with count of your data for collectionViewA
        }
    
        return 0 // Replace with count of your data for collectionViewB
    }
    
    0 讨论(0)
  • 2020-12-07 09:00

    Yes--this is entirely possible. You can either assign their respective UICollectionViewDelegates/UICollectionViewDataSources to different classes or subclass the CollectionViews, assigning both the delegate and data source to your current viewController and downcast your reference to collectionView in the delegation methods like so:

    @IBOutlet collectionViewA: CustomCollectionViewA!
    @IBOutlet collectionViewB: CustomCollectionViewB!
    
    
    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    
        if let a = collectionView as? CustomCollectionViewA {
            return a.dequeueReusableCellWithIdentifier("reuseIdentifierA", forIndexPath: indexPath)
        } else {
            return collectionView.dequeueReusableCellWithIdentifier("reuseIdentifierB", forIndexPath: indexPath)    
        }
    }
    

    Subclass UICollectionView like this:

    class CustomCollectionViewA: UICollectionView {
        // add more subclass code as needed
    }
    
    class CustomCollectionViewB: UICollectionView {
        // add more subclass code as needed
    }
    
    0 讨论(0)
  • 2020-12-07 09:06

    You can use the factory design pattern to build two different collection views and return them via functions. Here's my working version for swift 4.

    This code goes in a separate helper file:

    import UIKit
    
    class collectionViews {
    
    static func collectionViewOne() -> UICollectionView {
    
        let layout = UICollectionViewFlowLayout()
        let collectionViewOne = UICollectionView(frame: CGRect(x: 0, y: 20, width: 200, height: 100), collectionViewLayout: layout)
        return collectionViewOne
    
    }
    
    static func collectionViewTwo() -> UICollectionView {
    
        let layout = UICollectionViewFlowLayout()
        let collectionViewTwo = UICollectionView(frame: CGRect(x: 0, y: 300, width: 200, height: 100), collectionViewLayout: layout)
        return collectionViewTwo
    
    }
    
    
    }
    

    And here is the view controller code:

    import UIKit
    
    class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {
    
    
    let collectionViewOne = collectionViews.collectionViewOne()
    let collectionViewTwo = collectionViews.collectionViewTwo()
    
    var myArray = ["1", "2"]
    var myArray2 = ["3", "4"]
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
    
        collectionViewOne.delegate = self
        collectionViewOne.dataSource = self
        collectionViewOne.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "MyCell")
        view.addSubview(collectionViewOne)
    
    
        collectionViewTwo.delegate = self
        collectionViewTwo.dataSource = self
        collectionViewTwo.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "MyCell2")
        view.addSubview(collectionViewTwo)
    
    }
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    
        if collectionView == self.collectionViewOne {
            return myArray.count
        } else {
            return myArray2.count
        }
    
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    
        if collectionView == self.collectionViewOne {
            let myCell = collectionView.dequeueReusableCell(withReuseIdentifier: "MyCell", for: indexPath as IndexPath)
    
            myCell.backgroundColor = UIColor.red
    
            return myCell
    
        } else {
    
            let myCell2 = collectionView.dequeueReusableCell(withReuseIdentifier: "MyCell2", for: indexPath as IndexPath)
    
            myCell2.backgroundColor = UIColor.blue
    
            return myCell2
        }
    
    }
    
    
    }
    

    Result

    0 讨论(0)
  • 2020-12-07 09:08

    Here's my working version for swift 5 and Xcode 11:

    create outlets for corresponding collectionviews: outlets:

    @IBOutlet weak var bgCollectionView: UICollectionView!
    @IBOutlet weak var frontCollectionView: UICollectionView!
    var arrImages = [String : [UIImage]]()
    

    arrImages is contain like

    override func viewDidLoad() {
            super.viewDidLoad()
        arrImages = [
        "frontImg": [//Front UIImage array],
        "bgImg": [//Background UIImage array]
        ]
    }
    
     func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
            if let arrImg = arrImages["bgImg"] {
                return arrImg.count
            } else if let arrImg = arrImages["frontImg"]{
                return arrImg.count
            }
            return 0
        }
    

    You can do this two ways

    1. Using CollectionView Outlets
    
        func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell    
        if collectionView == self.bgCollectionView{
                if let arrImg = arrImages["bgImg"]{
                    cell.imgView.image = arrImg[indexPath.row]
                }
            }else{
                if let arrImg = arrImages["frontImg"]{
                    cell.imgView.image = arrImg[indexPath.row]
                }
            }
            return cell
        }
    
    1. Using CollectionView Tag: Here Background Images collectionview tag is 1 and Front Images collectionview tag is 2.

      
      func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
          let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell
          if collectionView == collectionView.viewWithTag(1){
              if let arrImg = arrImages["bgImg"]{
                  cell.imgView.image = arrImg[indexPath.row]
              }
          }else{
              if let arrImg = arrImages["frontImg"]{
                  cell.imgView.image = arrImg[indexPath.row]
                  }
              }
              return cell
          }
       

    Please Add Tag in CollectionView Like this:

    Thank You. Hope It's working for you !!

    0 讨论(0)
  • 2020-12-07 09:09

    You can also name the collection views outlets differently (without subclassing):

    @IBOutlet weak var collectionView: UICollectionView!
    
    @IBOutlet weak var SecondCollectioView: UICollectionView!
    

    method:

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "customCell", for: indexPath) as UICollectionViewCell
    
        if(collectionView == self.SecondCollectioView) {
            cell.backgroundColor = UIColor.black
        } else {
             cell.backgroundColor = self.randomColor()
        }
    
        return cell;
    }
    

    This is will be an another way.

    0 讨论(0)
提交回复
热议问题