Как получить выбранный IndexPath из степпера, расположенного внутри ячейки представления коллекции? - PullRequest
0 голосов
/ 12 декабря 2018

У меня есть представление коллекции, в котором внутри ячейки представления коллекции используется шаговый элемент, используемый для увеличения количества продуктов, как на изображении ниже.

enter image description here

Мне нужночтобы знать, когда я щелкаю степпер в ячейке представления коллекции.как мне узнать indexPath.item этой ячейки представления коллекции?чтобы я мог изменить данные, используя выбранный indexPath в контроллере View?

поэтому, если я изменю шаговый регулятор во второй ячейке, я всегда получу indexPath.item = 1

, как я ранее думалчто indexPath придет из didSelectItemAt метода ниже.но кажется, что didSelectItemAt метод не будет запущен, когда я коснусь степпера внутри ячейки представления коллекции.

  func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

    }

, поэтому я думаю, что могу получить indexPath из cellForRowAt IndexPath ииспользуя шаблон делегата протокола.Вот метод, который я сделал, , и я получил неправильный indexPath

Так что, если я изменю степпер во второй ячейке, я НЕ всегда получу indexPath.item = 1, это может быть2,3,0 и т. Д.

вот код контроллера представления:

class WishListVC: UIViewController, ListProductCellDelegate {

    var products = [Product]()
    var selectedProduct : Product?

     // method from ListProductCellDelegate
    func stepperButtonDidTapped(at selectedIndexPath: IndexPath, stepperValue: Int) {

        // get selectedIndexPath
        // perform some action based on selectedIndexPath

    }
}

extension WishListVC : UICollectionViewDataSource, UICollectionViewDelegate {

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

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

        guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: WishListStoryboardData.CollectionViewIdentifiers.productSliderCell.rawValue, for: indexPath) as? ListProductCell else { return UICollectionViewCell()}


        cell.productData = products[indexPath.item]
        cell.indexPath = indexPath // I send the indexPath to the cell.
        cell.delegate = self

        return cell
    }

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

        selectedProduct = products[indexPath.item]
        performSegue(withIdentifier: WishListStoryboardData.SegueIdentifiers.toProductVC.rawValue, sender: nil)
    }


}

, а вот код в ячейке представления коллекции:

protocol ListProductCellDelegate {
    func stepperButtonDidTapped( at selectedIndexPath: IndexPath, stepperValue: Int)
}

class ListProductCell: UICollectionViewCell {

    var indexPath: IndexPath?
    var delegate: ListProductCellDelegate?

    var productData : Product? {
        didSet {
            updateUI()
        }
    }

    @IBAction func stepperDidTapped(_ sender: GMStepper) {
        guard let indexPath = indexPath, let collectionView = collectionView else {return}
        self.delegate?.stepperButtonDidTapped(at: indexPath, stepperValue: Int(sender.value))
    }


    func updateUI() {
        // update the UI in cell.
    }
}

Ответы [ 3 ]

0 голосов
/ 12 декабря 2018

Вы можете попробовать добавить свойство tag к степперу.Поэтому, когда вы нажимаете на степпер, вы можете прослушать его селектор и определить, какой степпер был вызван.Значение тега должно совпадать с индексом элемента.

Примерно так:

cell.stepper.tag = indexPath.row

Над кодом должен идти внутри функции делегата cellForRowAt. * ​​1007 *

, а затем, когда пользователь нажимаетна шаговом вызовите функцию и проверьте значение тега

как то так

func stepperClicked(sender) {
    //check sender.tag value
    //Do something here with the tag value
}
0 голосов
/ 12 декабря 2018

В Swift закрытие обратного вызова , вероятно, является наиболее эффективным решением.Он не зависит от путей индекса, тегов, иерархии представлений math и протоколов.

В ячейку добавляется свойство callback, которое передает экземпляр степпера.Удалите indexPath и delegate.Протокол вообще не нужен.

В IBAction вызовите callback и передайте экземпляр stepper

class ListProductCell: UICollectionViewCell {

    var callback: ((GMStepper) -> Void)?

    var productData : Product? {
        didSet {
            updateUI()
        }
    }

    @IBAction func stepperDidTapped(_ sender: GMStepper) {
        callback?(sender)
    }


    func updateUI() {
        // update the UI in cell.
    }
}

В контроллере в cellForItemAt установите закрытие и обработайтеПерезвоните.Путь индекса фиксируется в методе.

И не guard ячеек.Заставь его развернуть.Код не должен падать.Если это так, то обнаруживается ошибка design .При способе guard табличное представление ничего бы не отображало, и вы не знаете почему.

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: WishListStoryboardData.CollectionViewIdentifiers.productSliderCell.rawValue, for: indexPath) as! ListProductCell
    cell.productData = products[indexPath.item]
    cell.callback = { stepper in 
       // handle the callback
    }
    return cell
}
0 голосов
/ 12 декабря 2018

У вас есть степпер, потому что это sender в вашем методе действия.Степпер имеет суперпредставление, которым является клетка (вам может понадобиться пройти более одного суперпредставления, чтобы добраться до клетки)Если у вас есть ячейка, вы можете позвонить indexPath(for:), чтобы получить индексный путь.Готово.

https://developer.apple.com/documentation/uikit/uicollectionview/1618094-indexpath

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...