0
votes

How do I send data from a button click in a uicollectionview inside of a popup to a table cell in a main view controller?

I have a UITableView with custom cells. When I click on the "1" inside of the cell, it brings up a popover. The popover used a UIView with a UICollectionView as a subview. Inside of the collection view is custom cells that each have a button. The desired behavior is to click a button in the popover and have that button execute a function through a delegate and set the button title for the button inside of the custom UITableViewCell in the main view controller.

MainViewController:

import UIKit

class MainViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, ListItemCellDelegate, PopoverCellDelegate {

...

func setPriority(buttonTitle: String) {
    print("Button Pressed")
}

PopoverCell:

import UIKit
import Foundation

protocol PopoverCellDelegate: class {
    func setPriority(buttonTitle: String)
}

class PopoverCell: UICollectionViewCell {
weak var delegate: PopoverCellDelegate?

let cellView: UIView = {
    let view = UIView()
    view.backgroundColor = UIColor.white
    view.setCellShadow()
    return view
}()

let priorityButton: UIButton = {
    let button = UIButton(type: .custom)

    //        button.setImage(UIImage(named: "UnChecked"), for: .normal)
    //        button.setImage(UIImage(named: "Checked"), for: .selected)
    button.frame = CGRect(x: 0, y: 0, width: 60, height: 60)
    button.setTitleColor(.black, for: .normal)
    button.backgroundColor = UIColor.white
    button.layer.borderWidth = 2
    button.layer.borderColor = UIColor.black.cgColor
    button.titleLabel?.font = UIFont.init(name: "Avenir Next", size: 24)
    return button
}()

override func awakeFromNib() {
    super.awakeFromNib()
    // Initialization code
}

override func prepareForReuse() {
    super.prepareForReuse()
    self.delegate = nil
}

override init(frame: CGRect) {
    super.init(frame: frame)
    setupCell()
    priorityButton.addTarget(self, action: #selector(setPriority), for: .touchUpInside)
}

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

func setupCell() {
    cellView.translatesAutoresizingMaskIntoConstraints = false
    priorityButton.translatesAutoresizingMaskIntoConstraints = false

    addSubview(cellView)
    cellView.addSubview(priorityButton)

    cellView.heightAnchor.constraint(greaterThanOrEqualToConstant: 60).isActive = true
    cellView.setAnchor(top: topAnchor, left: leftAnchor, bottom: bottomAnchor, right: rightAnchor, paddingTop: 8, paddingLeft: 4, paddingBottom: 8, paddingRight: 4)
    priorityButton.setAnchor(top: cellView.topAnchor, left: cellView.leftAnchor, bottom: cellView.bottomAnchor, right: cellView.rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 60, height: 60)
    priorityButton.centerXAnchor.constraint(equalTo: cellView.centerXAnchor).isActive = true
}

@objc private func setPriority() {
    if let title = priorityButton.currentTitle {
        print(title)
        self.delegate?.setPriority(buttonTitle: title)
    }

}
}

Screenshot

1

1 Answers

1
votes

Your cells don't need to and shouldn't communicate directly with the popover. Seeing that you already have the table view rendered with at least one cell in it, I assume you've already set up a datasource for it (UITableViewDataSource). That's great, you're half way there. When you load the screen (i.e., a view controller), the tableview asks the data source how to render its cells for each row (cellForRowAtIndexPath:) where I assume you set the label ("test") and assign a value for that 1 in a box.

Now you need to read in the value from the popover, report it back to your controller that will then tell the tableview to reload. You'll need to set up another delegate for the popover control that will send whatever value was tapped in a callback. Note that you should only need one instance of the popover, you don't need one for each row. Say your popover's delegate method is called didSelectValue:, once it's invoked, you should update the tableview's datasource with the new value and then call either tableView.reloadData() or if you want to be more surgical, tableView.reloadRows(at:with:). The tableview will reload its rows and the new value from its datasource (via the popover) will be shown. Hope this helps.