it-roy-ru.com

UITableViewCell Кнопки с действием

Привет, у меня есть пользовательский UITableViewCell с тремя кнопками для работы с корзиной покупок, кнопками «Плюс», «Минус» и «Удалить», и мне нужно знать, к какой ячейке прикоснулись. 

Я уже пытался использовать «решение тегов», но оно не работает из-за жизненного цикла ячеек. 

Может кто-нибудь, пожалуйста, помогите мне найти решение?

Заранее спасибо 

6
jack87

Я решал это с помощью метода делегата ячейки в подклассе UITableViewCell.

Краткая информация:

1) Создать протокол

protocol YourCellDelegate : class {
    func didPressButton(_ tag: Int)
}

2) Подкласс yourUITableViewCell(если вы этого не сделали):

class YourCell : UITableViewCell
{
     var cellDelegate: YourCellDelegate?   
      @IBOutlet weak var btn: UIButton!
    // connect the button from your cell with this method
    @IBAction func buttonPressed(_ sender: UIButton) {
        cellDelegate?.didPressButton(sender.tag)
    }         
    ...
}

3) Позвольте ваш взгляд контроллер соответствовать протоколу YourCellDelegate, который был реализован выше.

class YourViewController: ..., YourCellDelegate {  ... }

4) Установить делегата , после определения ячейки (для повторного использования).

let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! YourCell
cell.cellDelegate = self
cell.btn.tag = indexPath.row

5) В том же контроллере (где находится реализованный вами делегат UITableView/источник данных), поместите метод из протокола YourCellDelegate.

func didPressButton(_ tag: Int) {
     print("I have pressed a button with a tag: \(tag)")
}

Теперь ваше решение не зависит от тега/номера. Вы можете добавить столько кнопок, сколько захотите, так что вы готовы получать ответ через делегата независимо от того, сколько кнопок вы хотите установить.

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

42
pedrouan

После того как IBOutlets стали частными, я столкнулся с той же проблемой, которая была широко предложена сообществом.

Вот мое решение:

<В вашем классе клетки>

protocol YourCellDelegate: class {
    func didTapButton(_ sender: UIButton)
}

class YourCell: UITableViewCell {

    weak var delegate: YourCellDelegate?

    @IBAction func buttonTapped(_ sender: UIButton) {
        delegate?.didTapButton(sender)
    }
}

<В вашем ViewController>

class ViewController: UIViewController, YourCellDelegate {

    func didTapButton(_ sender: UIButton) {
        if let indexPath = getCurrentCellIndexPath(sender) {
            item = items[indexPath.row]
        }
    }

    func getCurrentCellIndexPath(_ sender: UIButton) -> IndexPath? {
        let buttonPosition = sender.convert(CGPoint.zero, to: tableView)
        if let indexPath: IndexPath = tableView.indexPathForRow(at: buttonPosition) {
            return indexPath
        }
        return nil
    }
}
11
Frederico

Вы также можете получить выбранный индекс кнопки, используя иерархию представления tableViewCell.

Используя следующие шаги:

  1. добавить селектор в cellForRowAtIndexpath таблицы:

    btn?.addTarget(self, action:#selector(buttonPressed(_:)), for:.touchUpInside)
    

2 получить indexPath, используя следующий метод: 

func buttonPressed(_ sender: AnyObject) {
        let button = sender as? UIButton
        let cell = button?.superview?.superview as? UITableViewCell
        let indexPath = tblview.indexPath(for: cell!)
        print(indexPath?.row)
    }
3
KKRocks

Swift 4. *

Это также можно сделать следующим образом, не требует большого количества кодирования и делегирования, просто и легко.

Поместите следующий код в cellForItemAt для UICollectionView или в cellForRowAt для UITableView 

cell.btn.tag = indexPath.row
cell.btn.addTarget(self, action: #selector(buttonSelected), for: .touchUpInside)

И ваш метод будет 

@objc func buttonSelected(sender: UIButton){
    print(sender.tag)
}

Это все.

2
Abhishek Mitra

@pedrouan великолепен, за исключением использования кнопки tag. Во многих случаях, когда вы устанавливаете кнопку на tableViewCell, эти кнопки изменят источник данных tableView (например, InsertRow, DeleteRow). 

Но тег кнопки не обновляется, даже если новая ячейка inserted или deleted. Поэтому лучше передать сам cell в качестве параметра, чем передавать tag кнопки в параметр.

Вот мой пример для достижения этой цели.

Ваш ExampleCell

protocol ExampleCellDelegate: class {
    func didTapButton(cell: ExampleCell)
}

class ExampleCell: UITableViewCell {

    weak var cellDelegate: ExampleCellDelegate?

    @IBAction func btnTapped(_ sender: UIButton) {
        cellDelegate?.didTapButton(cell: self)
    }
}

Ваш ViewController

class ViewController: ExampleCellDelegate {
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if let cell = tableView.dequeueReusableCell(withIdentifier: "ExampleCell", for: indexPath) as? ExampleCell {

            cell.cellDelegate = self
            return cell
        }
        return UITableViewCell()
    }

    func didTapButton(cell: ExampleCell) {
        if let indexPath = tableView.indexPath(for: cell) {
            // do Something
        }
    }
}
0
Changnam Hong

UIButton в Uitableviewcell. Программно создать метод действия в Swift 4.2

cell.btnlike.addTarget(self, action: #selector(buttonbtnlikePressed(_:event:)), for: .touchUpInside)


@objc func buttonbtnlikePressed(_ sender: Any, event: Any) {
        let point : CGPoint = (sender as AnyObject).convert(CGPoint.zero, to:tblPost)
        var indexPath =  self.tblPost!.indexPathForRow(at: point)
        if let btnlike = sender as? UIButton{
            if btnlike.isSelected{
                btnlike.isSelected = false
            }else{
                btnlike.isSelected = true
            }
        }
    }
0
Himanshu Moradiya