Как получить текущий элемент CollectionViewCell, используя кнопку в ячейке? - PullRequest
0 голосов
/ 16 ноября 2018

У меня есть вопрос о поиске выбранного элемента моих 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?()
    }

}

Вот мой cellForItemAt в главном контроллере View:

 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 голосов
/ 16 ноября 2018

Ваш подход не совсем верен.

В вашем закрытии .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

    }

}

Или другой подход ... Удалите переход с раскадровки и измените свой .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)
    }
...