如何使用单元格中的按钮获取CollectionViewCell的当前项目?

时间:2018-11-15 21:21:12

标签: ios swift database uicollectionview uicollectionviewcell

我对查找CollectionViewCells的选定项目有疑问。我想将数据带到另一个ViewController,然后编辑并将其保存到我的单元格的选定项目吗?问题是我当前的项目始终为0,所以我的第一个CollectionCell是?我用于测试ItemList.txt文件。

其中一个单元格:

One of the Cells

这是我的EditViewController:

class EditViewController: UIViewController {
    var itemList = ListItem.load() {
        didSet {
            ListItem.save(itemList)
        }
    }

    @IBOutlet weak var editTextField: UITextField!
    @IBOutlet weak var editView: UIView!

    //var currentItem = 0
    var currentText = ""
    var currentItem = 0

    override func viewDidLoad() {
        super.viewDidLoad()

        editTextField.text = itemList[currentItem]

        editView.clipsToBounds = true
        editView.layer.borderColor = UIColor.black.cgColor
        editView.layer.cornerRadius = 25
    }

    @IBAction func saveButton(_ sender: Any) {
        self.dismiss(animated: true, completion: nil)
        editTextField.resignFirstResponder()
    }

    @IBAction func cancelButton(_ sender: Any) {
        self.dismiss(animated: true, completion: nil)
        editTextField.resignFirstResponder()
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        self.editView.endEditing(true)
    }

}

这是我的CollectionViewCell:

class CollectionViewCell: UICollectionViewCell {
    var btnTapAction : (()->())?

    @IBOutlet weak var listLabel: UILabel!
    @IBOutlet weak var editButton: UIButton!

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        self.layer.cornerRadius = self.frame.size.width * 0.1
        self.layer.borderWidth = 0
        self.layer.borderColor = UIColor(red: 0.5, green: 0.47, blue: 0.25, alpha: 1.0).cgColor
    }

    @IBAction func editButtonTapped(_ sender: UIButton) {
        print("Tapped!")

        btnTapAction?()
    }

}

在主ViewController中的cellForItemAt:

 func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
            let cell : CollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionViewCell", for: indexPath) as! CollectionViewCell
            cell.listLabel.text = itemList[indexPath.row]

            cell.editButton.addTarget(self, action: #selector(editButtonTapped), for: UIControl.Event.touchUpInside)
            cell.editButton.tag = indexPath.item
            cell.editButton.isUserInteractionEnabled = true

            cell.btnTapAction = { () in
                print("Edit tapped in cell", indexPath.item)
                // start your edit process here...
                let storyboard = UIStoryboard(name: "Main", bundle: nil)
                let viewController = storyboard.instantiateViewController(withIdentifier: "edit") as! EditViewController
                viewController.currentItem = indexPath.item
                print("\(viewController.currentItem)")
            }

            return cell
  }

这是我的ViewCollectionViewCell:

class CollectionViewCell: UICollectionViewCell {
    
    var btnTapAction : (()->())?
    
    @IBOutlet weak var listLabel: UILabel!
    @IBOutlet weak var editButton: UIButton!
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        
        self.layer.cornerRadius = self.frame.size.width * 0.1
        self.layer.borderWidth = 0
        self.layer.borderColor = UIColor(red: 0.5, green: 0.47, blue: 0.25, alpha: 1.0).cgColor
    }
    
    @IBAction func editButtonTapped(_ sender: UIButton) {
        print("Tapped!")
        
        btnTapAction?()
    }
    
}

也许对此有一个答案,但我没有找到。

1 个答案:

答案 0 :(得分:0)

您的方法并不完全正确。

在您的.btnTapAction闭包中,创建一个EditViewController的新实例。但是,一旦关闭关闭,该实例就不再存在。

    cell.btnTapAction = { () in
        // you tapped the button
        // this line prints the indexPath.item to the console
        print("Edit tapped in cell", indexPath.item)

        let storyboard = UIStoryboard(name: "Main", bundle: nil)

        // here, you create an instance of EditViewController
        let viewController = storyboard.instantiateViewController(withIdentifier: "edit") as! EditViewController

        // here, you set .currentItem in the instance of EditViewController
        viewController.currentItem = indexPath.item

        // you print that value to the console
        print("\(viewController.currentItem)")

        // here, the closure exits, and
        // viewController no longer exists!
    }

在运行该代码的同时,您的Segue正在创建其 自己 的EditViewController实例。

这就是.currentItem始终为零的原因。

相反,您需要将indexPath.item保存在类级变量中,然后在.currentItem内设置prepare(for segue: ...)

class YourCollectionViewController: UICollectionViewController {

    var selectedItem = 0

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

        if let newEditVC = segue.destination as? EditViewController {
            newEditVC.currentItem = self.selectedItem
        }

    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell : CollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionViewCell", for: indexPath) as! CollectionViewCell
        cell.listLabel.text = itemList[indexPath.row]

        cell.editButton.addTarget(self, action: #selector(editButtonTapped), for: UIControl.Event.touchUpInside)
        cell.editButton.tag = indexPath.item
        cell.editButton.isUserInteractionEnabled = true


        cell.btnTapAction = { () in
            // you tapped the button
            // this line prints the indexPath.item to the console
            print("Edit tapped in cell", indexPath.item)

            // set your class-level variable
            // which will be used in prepare(for segue: ...)
            self.selectedItem = indexPath.item
        }

        return cell

    }

}

或者,另一种方法...从情节提要中删除Segue,然后将您的.btnTapAction更改为此:

    cell.btnTapAction = { () in
        // you tapped the button
        // this line prints the indexPath.item to the console
        print("Edit tapped in cell", indexPath.item)

        let storyboard = UIStoryboard(name: "Main", bundle: nil)

        // here, you create an instance of EditViewController
        let viewController = storyboard.instantiateViewController(withIdentifier: "edit") as! EditViewController

        // here, you set .currentItem in the instance of EditViewController
        viewController.currentItem = indexPath.item

        // you print that value to the console
        print("\(viewController.currentItem)")

        // present that instance of EditViewController
        self.present(viewController, animated: true, completion: nil)
    }