Search code examples
iosswiftuicollectionviewuicollectionviewcelluicollectionreusableview

Update cell content in UICollection2 from UICollection 1


I have 3 UICollections. The main UICollection that holds 2 cells which each contains a UI Collection.

In the first cell, from the main UICollection, a vertical collection with 3 cells is loaded.

In the second cell, from the main UICollection, a one cell uicollection view is created.

enter image description here

See image above: The main UICollectionView is represented in yellow, the 2 cells each are represented by red and blue respectively.

The first cell (from main uicollection view) contains a uicollection with 3 cells(red). I want to update the blue uicollection view cell when I click(tap) on any(of the 3) cell located in the red uicollection.

FullScreenImage.swift

class FullScreenImage: UIViewController, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource{



let bottomUIColletion: UICollectionView = {
    let layout = UICollectionViewFlowLayout()
    layout.minimumLineSpacing = 0
    layout.minimumInteritemSpacing = 0
    layout.scrollDirection = .horizontal
    let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
    return cv
}()


let bottomContentCell = "buttonContentCell"
let bottomButtonsCell = "buttonButtonsCell"



override func viewDidLoad() {
    super.viewDidLoad()
    self.bottomUIColletion.delegate = self
    self.bottomUIColletion.dataSource = self
    self.bottomUIColletion.register(BottomButtonsCollectionViewCell.self, forCellWithReuseIdentifier: bottomButtonsCell)
    self.bottomUIColletion.register(BottomContentCollectionViewCell.self, forCellWithReuseIdentifier: bottomContentCell)

    self.bottomUIColletion.translatesAutoresizingMaskIntoConstraints = false

    self.view.addSubview(self.bottomUIColletion)

    DispatchQueue.main.async {

        self.bottomUIColletion.topAnchor.constraint(equalTo: self.bottomView.topAnchor, constant: 0).isActive = true
        self.bottomUIColletion.leadingAnchor.constraint(equalTo: self.bottomView.leadingAnchor, constant: 0).isActive = true
        self.bottomUIColletion.trailingAnchor.constraint(equalTo: self.bottomView.trailingAnchor, constant: 0).isActive = true
        self.bottomUIColletion.heightAnchor.constraint(equalToConstant: self.bottomView.frame.height).isActive = true


    }


}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {

    return 2
}



func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

    if indexPath.row == 0{
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: bottomButtonsCell, for: indexPath) as! BottomButtonsCollectionViewCell
        return cell
    }

    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: bottomContentCell, for: indexPath) as! BottomContentCollectionViewCell

    return cell

}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    if indexPath.row == 0 {
        return CGSize(width: 50, height: self.bottomUIColletion.frame.height)
    }

    return CGSize(width: self.bottomUIColletion.frame.width-50, height: self.bottomUIColletion.frame.height)
}


func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
    return UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
}




}

BottomButtonsCollectionViewCell.swift

import UIKit
import FontAwesome_swift

class BottomButtonsCollectionViewCell: UICollectionViewCell, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {

override init(frame: CGRect) {
    super.init(frame: frame)
    setup()
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

let parentCollection = FullScreenImage()
let otherController = BottomContentCollectionViewCell()

let buttonCollection: UICollectionView = {
    let layout = UICollectionViewFlowLayout()
    layout.minimumLineSpacing = 0
    layout.minimumInteritemSpacing = 0
    layout.scrollDirection = .vertical
    let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
    cv.backgroundColor = UIColor.clear
    return cv
}()

let buttonCell = "buttonCell"

func setup(){

    buttonCollection.delegate = self
    buttonCollection.dataSource = self

    buttonCollection.register(ButtonLayout.self, forCellWithReuseIdentifier: buttonCell)

    buttonCollection.translatesAutoresizingMaskIntoConstraints = false

    addSubview(buttonCollection)

    buttonCollection.leadingAnchor.constraint(equalTo: self.safeAreaLayoutGuide.leadingAnchor, constant: 0).isActive = true
    buttonCollection.trailingAnchor.constraint(equalTo: self.safeAreaLayoutGuide.trailingAnchor, constant: 0).isActive = true
    buttonCollection.topAnchor.constraint(equalTo: self.safeAreaLayoutGuide.topAnchor, constant: 0).isActive = true
    buttonCollection.bottomAnchor.constraint(equalTo: self.safeAreaLayoutGuide.bottomAnchor, constant: 0).isActive = true


 }

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return 3
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: buttonCell, for: indexPath) as! ButtonLayout
    if indexPath.row == 0{
        cell.actionBtn.setImage(UIImage(named: "font_size_icon_white"), for: .normal)
    }else if indexPath.row == 1{
        cell.actionBtn.titleLabel?.font = UIFont.fontAwesome(ofSize: 25, style: .solid )
        cell.actionBtn.setTitle(String.fontAwesomeIcon(name: .font), for: .normal)
    }else if indexPath.row == 2{
        cell.actionBtn.titleLabel?.font = UIFont.fontAwesome(ofSize: 25, style: .solid )
        cell.actionBtn.setTitle(String.fontAwesomeIcon(name: .palette), for: .normal)
    }

    return cell
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize(width: self.frame.width, height: self.frame.height / 3)
}


func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
    return UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
}

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {



    otherController.btnSelected = indexPath.row
        parentCollection.bottomUIColletion.reloadItems(at: parentCollection.bottomUIColletion.indexPathsForVisibleItems)




    parentCollection.bottomUIColletion.reloadData()
    parentCollection.bottomUIColletion.layoutIfNeeded()
    //parentCollection.bottomUIColletion.





}

}

class ButtonLayout: UICollectionViewCell{
override init(frame: CGRect) {
    super.init(frame:frame)
    setupCell()
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

let actionBtn = UIButton()


func setupCell(){
    backgroundColor = UIColor.darkGray
    actionBtn.translatesAutoresizingMaskIntoConstraints = false
    addSubview(actionBtn)

    actionBtn.leadingAnchor.constraint(equalTo: self.safeAreaLayoutGuide.leadingAnchor, constant: 10).isActive = true
    actionBtn.trailingAnchor.constraint(equalTo: self.safeAreaLayoutGuide.trailingAnchor, constant: -10).isActive = true
    actionBtn.topAnchor.constraint(equalTo: self.safeAreaLayoutGuide.topAnchor, constant: 10).isActive = true
    actionBtn.bottomAnchor.constraint(equalTo: self.safeAreaLayoutGuide.bottomAnchor, constant: -10).isActive = true

 }

}

BottomContentCollectionViewCell.swift

import UIKit

class BottomContentCollectionViewCell: UICollectionViewCell, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout{

var btnSelected = Int()

let contentCollection: UICollectionView = {
    let layout = UICollectionViewFlowLayout()
    layout.minimumLineSpacing = 0
    layout.minimumInteritemSpacing = 0
    layout.scrollDirection = .vertical
    let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
    cv.backgroundColor = UIColor.clear
    return cv
}()

let textCell = "textSizeCell"
let fontTypeCell = "fontCell"
let backgroundColorCell = "backgroundCell"
let defaultCellLayout = "defaultCellLayout"


override init(frame: CGRect) {
    super.init(frame: frame)
    setup()
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}



func setup(){

    contentCollection.delegate = self
    contentCollection.dataSource = self

    contentCollection.register(textSizeCell.self, forCellWithReuseIdentifier: textCell)
    contentCollection.register(fontCell.self, forCellWithReuseIdentifier: fontTypeCell)
    contentCollection.register(BackgroundContentCollectionViewCell.self, forCellWithReuseIdentifier: backgroundColorCell)
    contentCollection.register(defaultCell.self, forCellWithReuseIdentifier: defaultCellLayout)

    contentCollection.translatesAutoresizingMaskIntoConstraints = false

    addSubview(contentCollection)

    contentCollection.leadingAnchor.constraint(equalTo: self.safeAreaLayoutGuide.leadingAnchor, constant: 0).isActive = true
    contentCollection.trailingAnchor.constraint(equalTo: self.safeAreaLayoutGuide.trailingAnchor, constant: 0).isActive = true
    contentCollection.topAnchor.constraint(equalTo: self.safeAreaLayoutGuide.topAnchor, constant: 0).isActive = true
    contentCollection.bottomAnchor.constraint(equalTo: self.safeAreaLayoutGuide.bottomAnchor, constant: 0).isActive = true

}


func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return 1
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    print("Button Content Collection: \(btnSelected)")

    //var cell = UICollectionViewCell()

    switch btnSelected {
    case 0:
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: textCell, for: indexPath) as! textSizeCell
        print("I was called: textSizeCell viewcell")
        return cell

    case 1:
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: fontTypeCell, for: indexPath) as! fontCell
        cell.nameLabel.text = "Awe"
        print("I was called: fontcell viewcell")
        return cell

    case 2:
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: backgroundColorCell, for: indexPath) as! BackgroundContentCollectionViewCell
        print("I was called: backgroundCell viewcell")
        return cell

    default:
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: defaultCellLayout, for: indexPath) as! defaultCell
        print("I was called: defaultCell viewcell")
        return cell
    }


}


func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize(width: self.frame.width, height: self.frame.height)
}


func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
    return UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
}


}

class textSizeCell: UICollectionViewCell{
override init(frame: CGRect) {
    super.init(frame:frame)
    setupCell()
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

override func prepareForReuse() {
    super.prepareForReuse()
}

func setupCell(){
    backgroundColor = UIColor.purple
     print("textSizeCell called.")
}
}

class fontCell: UICollectionViewCell{
override init(frame: CGRect) {
    super.init(frame:frame)
    setupCell()
}

override func prepareForReuse() {
    super.prepareForReuse()

}

let nameLabel: UILabel = {
    let label  = UILabel()
    label.textAlignment = .center
    //label.adjustsFontSizeToFitWidth = true
    //label.minimumScaleFactor = 0.5
    label.font = label.font.withSize(10)
    label.textColor = UIColor.lightGray
    label.numberOfLines = 0
    label.translatesAutoresizingMaskIntoConstraints = false
    return label
}()

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}



func setupCell(){
    self.backgroundColor = UIColor.yellow
    addSubview(nameLabel)
    nameLabel.centerXAnchor.constraint(equalTo: self.safeAreaLayoutGuide.centerXAnchor, constant: 0).isActive = true
    nameLabel.centerYAnchor.constraint(equalTo: self.safeAreaLayoutGuide.centerYAnchor, constant: 0).isActive = true
    nameLabel.heightAnchor.constraint(equalToConstant: 40)
    print("Font Cell setupCell called.")

}
}



class defaultCell: UICollectionViewCell{
override init(frame: CGRect) {
    super.init(frame:frame)
    setupCell()
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

override func prepareForReuse() {
    super.prepareForReuse()
}

func setupCell(){
    backgroundColor = UIColor.white


}
}

I have been trying to reload the cell content based on the cell selected in didSelectItemAt at BottomButtonsCollectionViewCell.swift and then reloading the data but I have had no luck. When running the app, no reload happens.

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {



    otherController.btnSelected = indexPath.row
        parentCollection.bottomUIColletion.reloadItems(at: parentCollection.bottomUIColletion.indexPathsForVisibleItems)




    parentCollection.bottomUIColletion.reloadData()
    parentCollection.bottomUIColletion.layoutIfNeeded()
    //parentCollection.bottomUIColletion.





}

Did I miss something? I have been working on this for 2 days and I feel overwhelmed and a bit frustrated. Also, I may have overlooked any similar question in SO. If so, please point me in the right direction.

I really hope I explained myself here. Thank you for your input.


Solution

  • You create a delegate called RedCollectionViewDelegate, which will have didSelect(cell) function defined.

    define a variable weak var delegate : RedCollectionViewDelegate in your RedCollectionView

    When you are setting up the main collection view, you will have access to both RedCollectionView and BlueCollectionView.. Make the delegate either main collectionView or BlueCollection or both.. it is really up to you.

    Then define the function and do whatever you want.