Действие UIButton в ячейке таблицы
Я пытаюсь запустить действие для нажатия кнопки внутри ячейки представления таблицы. Следующий код находится в моем классе контроллера табличного представления.
Кнопка была описана как "да" в розетке в моем классе UITableViewCell, называемом requestCell.
Я использую Parse для сохранения данных и хочу обновить объект при нажатии кнопки. Мой массив objectsIds работает отлично, cell.yes.tag также печатает правильный номер в журналах, однако я не могу получить этот номер в моей "подключенной" функции, чтобы правильно выполнить мой запрос.
Мне нужен способ получить indexPath.row ячейки, чтобы найти правильный objectId.
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as requestsCell
// Configure the cell...
cell.name.text = requested[indexPath.row]
imageFiles[indexPath.row].getDataInBackgroundWithBlock{
(imageData: NSData!, error: NSError!) -> Void in
if error == nil {
let image = UIImage(data: imageData)
cell.userImage.image = image
}else{
println("not working")
}
}
cell.yes.tag = indexPath.row
cell.yes.targetForAction("connected", withSender: self)
println(cell.yes.tag)
return cell
}
func connected(sender: UIButton!) {
var query = PFQuery(className:"Contacts")
query.getObjectInBackgroundWithId(objectIDs[sender.tag]) {
(gameScore: PFObject!, error: NSError!) -> Void in
if error != nil {
NSLog("%@", error)
} else {
gameScore["connected"] = "yes"
gameScore.save()
}
}
}
Ответы
Ответ 1
Swift 4 и Swift 5:
Вам нужно добавить цель для этой кнопки.
myButton.addTarget(self, action: #selector(connected(sender:)), for: .touchUpInside)
И, конечно, вам нужно установить тег этой кнопки, поскольку вы ее используете.
myButton.tag = indexPath.row
Вы можете достичь этого, создав подкласс UITableViewCell. Используйте его в конструкторе интерфейсов, поместите кнопку на эту ячейку, подключите ее через розетку и все готово.
Чтобы получить тег в подключенной функции:
@objc func connected(sender: UIButton){
let buttonTag = sender.tag
}
Ответ 2
button.tag
ответ с использованием button.tag
как носителя информации, который нажал кнопку, был прочным и широко принят, но ограничен, так как тег может содержать только Int
.
Вы можете использовать Swift удивительные возможности закрытия, чтобы иметь большую гибкость и более чистый код.
Я рекомендую эту статью: Как правильно делать кнопки в ячейках таблицы с использованием закрытий Swift от Jure Zove.
Применимо к вашей проблеме:
-
Объявите переменную, которая может удерживать закрытие в вашей ячейке tableview, например
var buttonTappedAction : ((UITableViewCell) -> Void)?
-
Добавьте действие, когда нажата кнопка, которая выполняет только закрытие. Вы сделали это программно с cell.yes.targetForAction("connected", withSender: self)
но я предпочел бы @IBAction
outlet :-)
@IBAction func buttonTap(sender: AnyObject) {
tapAction?(self)
}
- Теперь передайте содержимое
func connected(sender: UIButton!) {... }
как замыкание на cell.tapAction = {<closure content here...>}
. Пожалуйста, обратитесь к статье для более точного объяснения и, пожалуйста, не забывайте прерывать эталонные циклы при захвате переменных из среды.
Ответ 3
Простой и легкий способ обнаружить событие кнопки и выполнить какое-либо действие
class youCell: UITableViewCell
{
var yourobj : (() -> Void)? = nil
//You can pass any kind data also.
//var user: ((String?) -> Void)? = nil
override func awakeFromNib()
{
super.awakeFromNib()
}
@IBAction func btnAction(sender: UIButton)
{
if let btnAction = self.yourobj
{
btnAction()
// user!("pass string")
}
}
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell = youtableview.dequeueReusableCellWithIdentifier(identifier) as? youCell
cell?.selectionStyle = UITableViewCellSelectionStyle.None
cell!. yourobj =
{
//Do whatever you want to do when the button is tapped here
self.view.addSubview(self.someotherView)
}
cell.user = { string in
print(string)
}
return cell
}
Ответ 4
Мы можем создать закрытие кнопки и использовать ее в cellForRowAtIndexPath
class ClosureSleeve {
let closure: () -> ()
init(attachTo: AnyObject, closure: @escaping () -> ()) {
self.closure = closure
objc_setAssociatedObject(attachTo, "[\(arc4random())]", self,.OBJC_ASSOCIATION_RETAIN)
}
@objc func invoke() {
closure()
}
}
extension UIControl {
func addAction(for controlEvents: UIControlEvents = .primaryActionTriggered, action: @escaping () -> ()) {
let sleeve = ClosureSleeve(attachTo: self, closure: action)
addTarget(sleeve, action: #selector(ClosureSleeve.invoke), for: controlEvents)
}
}
И затем в cellForRowAtIndexPath
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell = youtableview.dequeueReusableCellWithIdentifier(identifier) as? youCell
cell?.selectionStyle = UITableViewCell.SelectionStyle.none//swift 4 style
button.addAction {
//Do whatever you want to do when the button is tapped here
print("button pressed")
}
return cell
}
Ответ 5
class TableViewCell: UITableViewCell {
@IBOutlet weak var oneButton: UIButton!
@IBOutlet weak var twoButton: UIButton!
}
class TableViewController: UITableViewController {
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! TableViewCell
cell.oneButton.addTarget(self, action: #selector(TableViewController.oneTapped(_:)), for: .touchUpInside)
cell.twoButton.addTarget(self, action: #selector(TableViewController.twoTapped(_:)), for: .touchUpInside)
return cell
}
func oneTapped(_ sender: Any?) {
print("Tapped")
}
func twoTapped(_ sender: Any?) {
print("Tapped")
}
}
Ответ 6
Как Apple DOC
targetForAction: withSender:
Возвращает целевой объект, который отвечает действие.
Вы не можете использовать этот метод для установки цели для UIButton
.
Пытаться
addTarget (_: action: forControlEvents:) метод
Ответ 7
в Свифт 4
в cellForRowAt indexPath:
cell.prescriptionButton.addTarget(self, action: Selector("onClicked:"), for: .touchUpInside)
функция, которая запускается после нажатия пользователем кнопки:
@objc func onClicked(sender: UIButton){
let tag = sender.tag
}
Ответ 8
С Swift 5 это то, что у меня сработало !!
Шаг 1. Создание IBOutlet для UIButton в My CustomCell.swift
class ListProductCell: UITableViewCell {
@IBOutlet weak var productMapButton: UIButton!
//todo
}
Шаг 2. Добавлен метод действия в методе CellForRowAtIndex и предоставлена реализация метода в том же контроллере представления
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ListProductCell") as! ListProductCell
cell.productMapButton.addTarget(self, action: #selector(ListViewController.onClickedMapButton(_:)), for: .touchUpInside)
return cell
}
@objc func onClickedMapButton(_ sender: Any?) {
print("Tapped")
}