简体   繁体   English

从uiviewcontroller操纵uicollectionviewcell内部的uicollectionview

[英]Manipulate uicollectionview inside uicollectionviewcell from uiviewcontroller

I have a UIViewController containing a UICollectionView and within their UICollectionViewCell is embedded another UICollectionView structure 我有一个包含UICollectionView的UIViewController,并且在其UICollectionViewCell中嵌入了另一个UICollectionView 结构

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 我想在UIViewController中按BOTON,然后从那里在外部UICollectionView的单元格内更改UICollectionView的backgroundColor

My UIViewController class 我的UIViewController类

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 我的UICollectionViewCell类

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? 如何访问嵌入在主UIViewController的父collectionViewCell中的collectionView?

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. 另一个解决方案是在ExteriorCollectionViewCell添加一个观察者 ,并在点击按钮并在UIViewController内部调用IBAction方法时,使用后通知将该事件传递给观察者。

ie: 即:

Add the observer that will listen to your events inside your ExteriorCollectionViewCell : 添加观察者,该观察者将侦听您的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: 通过IBAction方法中的IBAction发送通知事件:

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. 但是,如果按钮在UICollectionViewCell ,则可以在UICollectionViewCell内使用IBAction方法,并在那里进行逻辑处理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM