I have a UIViewController containing a UICollectionView and within their UICollectionViewCell is embedded another UICollectionView structure
And visually looks like this: visually
I want to press BOTON in UIViewController and from there, change the backgroundColor of UICollectionView inside the cell of the outter UICollectionView
My UIViewController class
class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
@IBOutlet weak var scrollH: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
if let flowLayout = scrollH.collectionViewLayout as? UICollectionViewFlowLayout {
flowLayout.minimumLineSpacing = 0
}
setupMenuQuestion()
}
var uiview: UIView = {
let view1 = UIView()
view1.backgroundColor = UIColor.brown
return view1
}()
var uibutton: UIButton = {
let btn1 = UIButton()
btn1.setTitle("BOTON", for: .normal)
btn1.addTarget(self, action: #selector(presionoBoton), for: .touchUpInside)
return btn1
}()
@objc func presionoBoton() {
delegateExterior?.cambiarBackground()
}
var delegateExterior: ExteriorCollectionViewCellDelegate?
private func setupMenuQuestion() {
view.addSubview(uiview)
uiview.translatesAutoresizingMaskIntoConstraints = false
uiview.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 0).isActive = true
uiview.rightAnchor.constraint(equalTo: view.rightAnchor, constant: 0).isActive = true
uiview.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0).isActive = true
uiview.heightAnchor.constraint(equalToConstant: 30).isActive = true
uibutton.translatesAutoresizingMaskIntoConstraints = false
uiview.addSubview(uibutton)
uibutton.centerYAnchor.constraint(equalTo: uiview.centerYAnchor).isActive = true
uibutton.centerXAnchor.constraint(equalTo: uiview.centerXAnchor).isActive = true
uibutton.leftAnchor.constraint(equalTo: uiview.leftAnchor, constant: 7).isActive = true
uibutton.rightAnchor.constraint(equalTo: uiview.rightAnchor, constant: -7).isActive = true
uibutton.heightAnchor.constraint(equalTo: uiview.heightAnchor, multiplier: 0.8).isActive = true
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 3
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cellNumQuestion = collectionView.dequeueReusableCell(withReuseIdentifier: "celdaExterior", for: indexPath) as! ExteriorCollectionViewCell
return cellNumQuestion
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: view.frame.width, height: view.frame.height - 100)
}
}
My UICollectionViewCell Class
protocol ExteriorCollectionViewCellDelegate {
func cambiarBackground()
}
class ExteriorCollectionViewCell: UICollectionViewCell,
UICollectionViewDataSource, UICollectionViewDelegate,
UICollectionViewDelegateFlowLayout, ExteriorCollectionViewCellDelegate{
func cambiarBackground() {
collectionCelda.backgroundColor = UIColor.black
}
@IBOutlet weak var collectionCelda: UICollectionView!
override init(frame: CGRect) {
super.init(frame: frame)
let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
layout.minimumInteritemSpacing = 40
layout.minimumLineSpacing = 40
collectionCelda!.collectionViewLayout = layout
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 4
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
var cell = UICollectionViewCell()
cell = collectionView.dequeueReusableCell(withReuseIdentifier: "celdaInterior", for: indexPath)
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: frame.width - 20, height: 400)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets(top: 30.0, left: 0.0, bottom: 30.0, right: 0.0)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 40
}
}
I have seen another post similar to my problem but I do not know how to proceed
How to access a collectionView that is embedded in a parent collectionViewCell in the main UIViewController?
In your case, you didn't set the delegate you've created, you should set it inside:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cellNumQuestion = collectionView.dequeueReusableCell(withReuseIdentifier: "celdaExterior", for: indexPath) as! ExteriorCollectionViewCell
// Setting the delegate
delegateExterior = cellNumQuestion
return cellNumQuestion
}
Also, in order to avoid reference-cycle set your delegateExterior pointer to be weak:
weak var delegateExterior: ExteriorCollectionViewCellDelegate?
Another solution will be to add an observer inside ExteriorCollectionViewCell
and when the button is tapped and the IBAction method gets called inside your UIViewController
, use post notification to pass that event into your observer.
ie:
Add the observer that will listen to your events inside your ExteriorCollectionViewCell
:
NotificationCenter.default.addObserver(forName: NSNotification.Name(rawValue: "EventForCollectionView"),
object: nil,
queue: nil) { [weak self] (_) in
// This method will be invoked when you post notification from your IBAction method inside your UIVC
self?.YourCustomMethod()
}
Send your notification event from your IBAction inside the IBAction method:
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "EventForCollectionView"), object: nil)
But if the button is inside your UICollectionViewCell
you can just use IBAction method inside your UICollectionViewCell
and do your logic there.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.