Отправить строку и раздел через тег в кнопке 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:
- Создайте подкласс UIButton:
class CustomTaggedButton: UIButton {
var section: Int = 0
var row: Int = 0
}
- Назначьте 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
}
- При нажатии кнопки
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 логическое или значимое решение для этого конкретного ответа.
используйте комбинацию побитового сдвига и побитовых операций, чтобы упаковать информацию раздела и строки в одно значение тега.
- При назначении тегов:
let tag = (indexPath.section << 16) | indexPath.row
cell.button.tag = tag
- При извлечении раздела и строки:
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