Как правильно сделать кнопку удаления ячейки?

ios

#1

32

Как реализовать кнопку, как на картинке ‘x’, она должна удалять ячейку, в которой находится?

import UIKit

class UserViewController: UIViewController {

var users: [String] = []

func addUser(nameUser: String){
    users.append(nameUser)
    print(nameUser)
}

func deleteUser(at index: Int){
    users.remove(at: index)
    tableView.deleteRows(at: [indexPath], with: .automatic)
}


func loadData(){
    
}


@IBOutlet weak var tableView: UITableView!

@IBOutlet weak var textField: UITextField!



@IBAction func pushAddButton(_ sender: Any) {
    if textField.text != nil || textField.text == " " {
        addUser(nameUser: textField.text!)
        let indexPath = IndexPath(row: users.count - 1, section: 0)
        
        tableView.beginUpdates()
        tableView.insertRows(at: [indexPath], with: .automatic)
        tableView.endUpdates()
        
        textField.text = ""
        view.endEditing(true)
    } else {
        let ac = UIAlertController(title: nil, message: "Пожалуйста введите имя игрока", preferredStyle: .alert)
        let alertAction = UIAlertAction(title: "OK", style: .default, handler: nil)
        ac.addAction(alertAction)
        present(ac, animated: true, completion: nil)
    }
}




override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
}

}
extension UserViewController: UITableViewDelegate, UITableViewDataSource{

func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    
    return users.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! UserTableViewCell
    
    cell.textLabel?.text = users[indexPath.row]

// cell.deleteButton.addTarget(self, action: #selector(deleteUser(sender:)), for: .touchUpInside)

    return cell
}

}


#2

В классе вашей ячейки создайте делегат с одним методом, который будет принимать либо саму ячейку, либо индекс ячейки.
В классе ячейки сделайте обычный IBAction для вашей кнопки удаления. При нажатии на кнопку, вызывайте метод делегата и передавайте в него ячейку или индекс ячейки.
В вашем ViewController’e при заполнении ячейки, укажите у ячейки делегат на ваш ViewController.
После чего в вашем ViewController’e подпишитесь под протокол вашей ячейки и реализуйте в нем 1 метод. После чего всю логику по удалению ячейки, удаление записи из массива, а так же обновление таблицы - будете делать в этом методе.


#3

Я зеленый еще не понимаю, как это делать, подскажите правильно ли я делаю?

import UIKit

class UserTableViewCell: UITableViewCell, UITableViewDelegate {

@IBAction func pushDeleteButton(_ sender: Any) {
    delegateCell(indexPath: IndexPath)
}

@IBOutlet weak var cellTextLabel: UILabel!


func delegateCell(indexPath: IndexPath){
    
}



override func awakeFromNib() {
    super.awakeFromNib()
    // Initialization code
}

override func setSelected(_ selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)

    // Configure the view for the selected state
}

}


#4

в этом форуме уже несколько раз кидал кусок кода.
от кнопки в ячейке тяните метод удаления в контроллер. И там обрабатываете нажатия и удаляете соответствующий элемент. Там хитрость в том чтобы протянуть action с event-ом. А оттуда взять точку куда нажал пользователь и по этой точке уже найти индекс ячейки. Это 2мя строками реализуется, но из головы не вспомню.


#5

Вообще не понимаю, как это реализовать, если можете найдите эти 2 строчки кода


#6

разкомментируй код

cell.deleteButton.tag = indexPath.row
cell.deleteButton.addTarget(self, action: #selector(deleteUser(sender:)), for: .touchUpInside)

измени

@objc func deleteUser(sender: UIButton) {
let index = sender.tag
users.remove(at: index)
var indexPath = IndexPath()
indexPath.row = index
indexPath.section = 1
tableView.deleteRows(at: [indexPath], with: .automatic)
}

наслаждайся результатом бро :grinning:


#7

с делегатами не мучайся это муторно я тебе более простой и доступный способ показал


#8

Ок, давайте вариант проще разберем
Ваш класс ячейки

var deleteHandler: (() -> ())? = nil

@IBAction func deleteTap(_ sender: UIButton) {
    deleteHandler?()
}

Ваш ViewController

func tableView(cellForRowAt) -> UITableViewCell {
    let cell = ...

    cell.deleteHandler = {
        // ваша логика удаления или вызов метода
    }

    return cell
}

#9

Рекс ты сложные способы предлагаешь


#10

На это ошибка вылезает
Cannot convert value of type ‘Int’ to expected argument type ‘[IndexPath]’


#11

секунду бро пофиксим щас


#12

С делегатами - это основы и желательно это знать, т.к. они практически всегда используются.
А вот с добавлением таргета, я ниразу так не делал и очень редко вижу такое у спецов. И что-то мне подсказывает, что это не best practice.


#13

Где про это можно почитать/посмотреть?


#14

var indexPath = IndexPath()
indexPath.row = index
indexPath.section = 1
tableView.deleteRows(at: [indexPath], with: .automatic)

пробуй бро, если не сработает section на ноль поменяй


#15

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


#16

Cannot assign value of type ‘(Any) -> Int’ to type ‘Int’

Cannot convert value of type ‘(Any) -> Int’ to expected argument type ‘Int’


#17

покажи весь код который ты написал


#18

@objc func deleteUser(sender: UIButton) {
var indexPath = IndexPath()
indexPath.row = index
indexPath.section = 1
tableView.deleteRows(at: [indexPath], with: .automatic)
users.remove(at: index)
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: “Cell”, for: indexPath) as! UserTableViewCell

    cell.textLabel?.text = users[indexPath.row]
   cell.deleteButton.tag = indexPath.row
   cell.deleteButton.addTarget(self, action: #selector(deleteUser(sender:)), for: .touchUpInside)
 return cell
}

#19

вот выше я отредактировал ты индекс удалил
@objc func deleteUser(sender: UIButton) {
let index = sender.tag
users.remove(at: index)
var indexPath = IndexPath()
indexPath.row = index
indexPath.section = 1
tableView.deleteRows(at: [indexPath], with: .automatic)
}

ты взял просто старое на новое заменил, но там же не все нужно было менять :grinning:


#20

лучше писать так
guard let cell = tableView.dequeueReusableCell(withIdentifier: “Cell”) as? UserTableViewCell else { return UITableViewCell() }