Отправить строку и раздел через тег в кнопке Swift

У меня есть это внутри cellForRowAtIndexPath

   cell.plusBut.tag = indexPath.row
   cell.plusBut.addTarget(self, action: "plusHit:", forControlEvents: UIControlEvents.TouchUpInside)

и эта функция снаружи:

func plusHit(sender: UIButton!){
    buildings[sender.tag].something = somethingElse
}

Можно ли отправить indexPath.row а также indexPath.sectionили какая-то альтернатива??

Спасибо!

РЕДАКТИРОВАТЬ

Я подошел к этому так:

Моя Пользовательская Кнопка

class MyButton: UIButton{

    var myRow: Int = 0
    var mySection: Int = 0

}

Моя Таможенная Клетка

class NewsCell: UITableViewCell{

    @IBOutlet weak var greenLike: MyButton!

В CellForRowAtIndexPath

    cell.greenLike.myRow = indexPath.row

Я получаю ошибку в этой строке.

8 ответов

Решение

Вы можете создать подкласс UIButton и создайте в нем дополнительный раздел свойств. И тогда вы можете использовать этот класс для кнопки ячейки. Вы можете сделать то же самое для строки.

Вот несколько возможных способов после создания подклассов UIButton

cell.plusBut.tag = indexPath.row
cell.plusBut.section = indexPath.section

Или же

cell.plusBut.row = indexPath.row
cell.plusBut.section = indexPath.section

Или же

cell.plusBut.indexPath = indexPath

Выберите то, что вам подходит.

Можно ли отправить indexPath.row и indexPath.section или какую-то альтернативу??

Если вы наложите ограничение на количество возможных строк в разделе, вы можете объединить их в одно число. Например, если вы хотите сказать, что в данном разделе всегда будет меньше 1000 строк, вы можете использовать:

cell.plusBut.tag = (indexPath.section * 1000) + indexPath.row

а затем используйте мод и операторы деления для восстановления:

row = sender.tag % 1000
section = sender.tag / 1000

Другой возможностью является проверка суперпредставления кнопки (и ее суперпредставления и т. Д.), Пока вы не найдете ячейку. Если у вас есть ячейка, вы можете получить индексный путь для этой ячейки из таблицы.

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

Вот действительно простое решение, которое я использую:

в CellForRow:

button.tag = indexPath.row
cell.contentView.superview?.tag = indexPath.section

в функции восстановить это так:

func buttonTapped(_ sender: Any) {
    let button = sender as! UIButton
    let row = button.tag
    let sec = button.superview?.tag

    //retrieve item like self.array[sec][row]
    //do the rest of your stuff here
}

Swift 2.x - Расширение со связанными объектами

private struct AssociatedKeys {
static var section = "section"
static var row = "row"
}

extension UIButton {
var section : Int {
    get {
        guard let number = objc_getAssociatedObject(self,   &AssociatedKeys.section) as? Int else {
            return -1
        }
        return number
    }

    set(value) {
        objc_setAssociatedObject(self,&AssociatedKeys.section,Int(value),objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
    }
}
var row : Int {
    get {
        guard let number = objc_getAssociatedObject(self, &AssociatedKeys.row) as? Int else {
            return -1
        }
        return number
    }

    set(value) {
        objc_setAssociatedObject(self,&AssociatedKeys.row,Int(value),objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
    }
}
}

использование:

//set
cell.contextMenuBtn.section = indexPath.section
cell.contextMenuBtn.row = indexPath.row 
//read
func showContextMenu (sender:UIButton) {
    let track = dictionarySongs[sender.section][sender.row]
    ...
}

Отправить строку и раздел через кнопку, вы можете использовать тег и accessibilityIdentifier, посмотрите:

Установить значение

 button.tag = indexPath.row
 button.accessibilityIdentifier = "\(indexPath.section)"

Получить значение

let indexRow = button.tag
let indexSection = Int(button.accessibilityIdentifier!)

Вы можете назначить пользовательский тег для UIButton через расширение, посмотрите:

extension UIButton {

private struct ButtonTag {

    static var tagKey = "key"

}

var myTag : (Int , Int)? {

    set  {
        if let value = newValue {
            objc_setAssociatedObject(self, &ButtonTag.tagKey, value as! AnyObject, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }

    get {
        return objc_getAssociatedObject(self, &ButtonTag.tagKey) as? (Int , Int)
    }
  }   
}

Я предлагаю другой подход. Мне не нравится решение подкласса, я не думаю, что кнопка должна знать свою позицию. Почему бы не использовать словарь для перевода кнопки в IndexPath

// First initialize the lookup table
var buttonPositions = [UIButton: NSIndexPath]()

// add each button to the lookup table
let b = UIButton()
let path = NSIndexPath(forItem: 1, inSection: 1)


buttonPositions[b] = path

// Looking it up works like this
buttonPostions[activeButton]?.row  

Есть определенные возможные решения этого вопроса:

Решение 1:

  1. Создайте подкласс UIButton:
      class CustomTaggedButton: UIButton {
   var section: Int = 0
   var row: Int = 0
}
  1. Назначьте CustomTaggedButton вашей кнопке.
      func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "CellIdentifier", for: indexPath) as! CustomTableViewCell

    cell.button.section = indexPath.section
    cell.button.row = indexPath.row
    button.setTitle("Tap me", for: .normal)
    button.addTarget(self, action: #selector(buttonTapped(_:)), for: .touchUpInside)
    
    return cell
}
  1. При нажатии кнопки
      func buttonTapped(_ sender: CustomTaggedButton) {
    let section = sender.section
    let row = sender.row
    
    print("Button tapped - Section: \(section), Row: \(row)")
    
    // Use section and row as needed
}

Решение 2: /questions/18175126/otpravit-stroku-i-razdel-cherez-teg-v-knopke-swift/18175131#18175131 логическое или значимое решение для этого конкретного ответа.

используйте комбинацию побитового сдвига и побитовых операций, чтобы упаковать информацию раздела и строки в одно значение тега.

  1. При назначении тегов:
      let tag = (indexPath.section << 16) | indexPath.row
cell.button.tag = tag
  1. При извлечении раздела и строки:
      func buttonTapped(_ sender: UIButton) {
    let tag = sender.tag
    let section = (tag >> 16) & 0xFFFF
    let row = tag & 0xFFFF
        
    print("Button tapped - Section: \(section), Row: \(row)")
    
    // Use section and row as needed
}

Пример значения тега из раздела и строки:

      Tag for Section 0, Row 0: tag = (0 << 16) | 0 = 0
Tag for Section 1, Row 2: tag = (1 << 16) | 2 = 65538
Tag for Section 2, Row 3: tag = (2 << 16) | 3 = 131075
Другие вопросы по тегам