Swift 3:如何点击单元格内的按钮并传入该单元格的indexPath?

时间:2017-03-16 14:41:14

标签: swift uitableview swift3 uicollectionview uicollectionviewcell

我正在做所有以编程方式,避免故事板。我有一个collectionView,一个Post模型对象,它包含用户名和密码,当然我有collectionView单元格。我遇到的问题是我的collectionView Cells里面有一个按钮。我希望能够点击此按钮并进入新的控制器。这是简单的部分。问题是我不仅想要进入新的控制器,还要传递我点击的按钮的特定Post Cell的特定用户名。我希望这是有道理的。基本上我想要一个帖子,就像任何社交媒体应用程序一样,我想要进入一个"简介"并且还将该特定用户的用户名传递给该配置文件控制器。我希望你能理解这一点。任何帮助都将受到高度赞赏,因为我已经坚持了一段时间。我当然会标记为答案。谢谢你们......

class MyController: UICollectionViewController, UICollectionViewDelegateFlowLayout {

var posts = [Post]()

override func viewDidLoad() {
    super.viewDidLoad()

    collectionView?.backgroundColor = .white
    collectionView?.register(CustomCell.self, forCellWithReuseIdentifier: "cellId")
}

override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return posts.count
}

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

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId", for: indexPath) as! CustomCell

    cell.post = posts[indexPath.item]
    cell.homeController = self

    return cell
}

class CustomCell: UICollectionViewCell, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {

    var homeController: MyController?

    var post: Post? {
        didSet {
            if let username = post?.username {
                usernameLabel.text = username
            }
        }
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
        backgroundColor = .blue
        setupViews()
    }

    lazy var myButton: UIButton = {
        let btn = UIButton()
        btn.backgroundColor = .red
        btn.setTitle("Push", for: .normal)
        btn.isUserInteractionEnabled = false
        btn.addTarget(self, action: #selector(handleTapped), for: .touchUpInside)
        return btn
    }()

    let usernameLabel: UILabel = {
        let label = UILabel()
        label.textColor = .white
        return label
    }()

    func handleTapped() {
        let postController = PostController()
        homeController?.navigationController?.pushViewController(postController, animated: true)
    }

    func setupViews() {
        addSubview(myButton)

        myButton.frame = CGRect(x: (self.frame.width / 2) - 25, y: (self.frame.height / 2) - 25, width: 50, height: 50)
    }

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

2 个答案:

答案 0 :(得分:4)

我建议您告诉UIViewController CustomCell内的按钮已被点击。您可以添加协议,向您的单元格添加delegate属性,然后MyController必须符合协议。该函数还应传入已单击的单元格,您可以从indexPath获取该单元格的collectionView

protocol CustomCellDelegate: class {
    func didSelectButton(in cell: CustomCell)
}

class CustomClass: UICollectionViewClass {
    weak var delegate: CustomCelLDelegate?
    func handleTapped() {
        delegate?.didSelectButton(in: self)
    }
}

然后在你的MyController课程中,添加委托并遵守协议。

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId", for: indexPath) as! CustomCell

    cell.post = posts[indexPath.item]
    cell.delegate = self

    return cell
}

extension MyController: CustomCellDelegate {
    func didSelectButton(in cell: CustomCell) {
        if let indexPath = collectionView.indexPath(for: cell) {
            let postController = PostController()
            let post = posts[indexPath.row]
            postController.post = post //pass the data
            self.navigationController?.pushViewController(postController, animated: true)
        }
    }
}

您还需要向post添加PostController变量。

class PostController {
    var post: Post!
}

答案 1 :(得分:2)

您没有使用segue而不是使用navigationController推送ViewController。因此,使用postController对象传递值。

func handleTapped() {
    let postController = PostController()
    //Pass the detail that you want
    postController.selectedPost = self.post
    homeController?.navigationController?.pushViewController(postController, animated: true)
}

现在在PostController中声明一个名为Post的{​​{1}}类型的实例属性,然后在selectedPost中使用该对象来分配您的viewDidLoad

Labels