首页 > 解决方案 > 如何从弹出框内的 uicollectionview 中单击按钮将数据发送到主视图控制器中的表格单元格?

问题描述

如何从弹出窗口内的 uicollectionview 中单击按钮将数据发送到主视图控制器中的表格单元格?

我有一个带有自定义单元格的 UITableView。当我点击单元格内的“1”时,它会弹出一个弹出窗口。弹出框使用带有 UICollectionView 的 UIView 作为子视图。集合视图内部是自定义单元格,每个单元格都有一个按钮。所需的行为是单击弹出窗口中的按钮并让该按钮通过委托执行功能,并在主视图控制器中的自定义 UITableViewCell 内设置按钮的按钮标题。

主视图控制器:

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)
    }

}
}

截屏

标签: iosswiftdelegatesswift5

解决方案


您的单元格不需要也不应该直接与弹出框通信。看到您已经呈现了包含至少一个单元格的表格视图,我假设您已经为它设置了一个数据源(UITableViewDataSource)。太好了,你已经成功了一半。当您加载屏幕(即视图控制器)时,表格视图会询问数据源如何为每一行(cellForRowAtIndexPath:)呈现其单元格,我假设您在其中设置标签( )并在框中"test"为其分配一个值。1

现在您需要从弹出窗口中读取值,将其报告回您的控制器,然后控制器将告诉 tableview 重新加载。您需要为弹出框控件设置另一个委托,该委托将发送回调中点击的任何值。请注意,您应该只需要一个弹出框实例,而不需要每行一个。假设你的 popover 的委托方法被调用didSelectValue:,一旦它被调用,你应该用新值更新 tableview 的数据源,然后调用tableView.reloadData()或者如果你想要更外科手术,tableView.reloadRows(at:with:). 表格视图将重新加载其行,并显示来自其数据源(通过弹出框)的新值。希望这可以帮助。


推荐阅读