Добавить / удалить подпредставление и ограничения в UITableViewCell по нажатию кнопки - PullRequest
0 голосов
/ 09 октября 2018

У меня есть UITableView, который я использую, чтобы показать массив пользовательских объектов.Каждый объект имеет несколько свойств, включая логическое свойство, которое указывает, является ли этот элемент новым или нет.

Мое UITableViewCell представление содержимого определено в раскадровке и имеет первоначальный макет, подобный следующему:

enter image description here

В моем UITableViewController, когда я снимаю очередь с моих ячеек, я вызываю на своем UITableViewCell метод, который настраивает данные, которые будут отображаться в ячейке, прежде чем я вернусьЭто.Одним из свойств, которые я проверяю, является свойство .isNew, о котором я упоминал ранее.Если это значение равно true, тогда я создаю UIButton и вставляю его как подпредставление в представление содержимого ячейки, чтобы в итоге получилось что-то вроде этого:

enter image description here

Только для контекста, эта кнопка покажет «новое» изображение, чтобы указать, что этот элемент является новым.Я также подключаю метод, который будет срабатывать при нажатии кнопки.Этот метод также определен в моем UITableViewCell и выглядит следующим образом:

@objc func newIndicatorButtonTapped(sender: UIButton!) {
   // call delegate method and pass this cell as the argument
   delegate?.newIndicatorButtonTapped(cell: self)
}

Я также создал протокол, который определяет метод делегата.Мой UITableViewController соответствует этому, и я вижу, что код срабатывает, когда я нажимаю на кнопку в своих ячейках.Вот метод делегата (определенный в расширении на моем UITableViewController):

func newIndicatorButtonTapped(cell: UITableViewCell) {        
    if let indexPath = self.tableView.indexPath(for: cell) {
        print(indexPath.row)
    }
}

Я вижу строку из indexPath, правильно распечатанную в Xcode, когда я нажимаю на ячейку.Когда мой пользователь нажимает на эту кнопку, мне нужно удалить ее (кнопку) и обновить ограничение для моего UILabel, чтобы оно снова выровнялось по переднему краю представления содержимого, как показано в первом макете выше.К сожалению, я, похоже, столкнулся с проблемой повторного использования ячеек, потому что UIButton исчезает и снова появляется в разных ячейках, когда я их прокручиваю.Нужно ли сбрасывать компоновку / внешний вид ячейки, прежде чем она будет переработана, или я что-то неправильно понимаю о том, как работает утилизация ячейки?Любые советы будут высоко оценены!

Ответы [ 2 ]

0 голосов
/ 09 октября 2018

Возможно, вы захотите скрыть кнопку, а затем изменить ее при нажатии.

enter image description here

Хороший способ сделать это - запустить действие из ячейки в tableView с протоколом, а затем сбросить макет при повторном использовании ячейки

Выполнение этого в ячейке полностью программно будет выглядеть так:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! Cell
    cell.isNew = indexPath.row == 0 ? true : false
    cell.layoutIfNeeded()
    return cell
}

И класс ячейки должен быть похож на: (вы можете делать то, что вам нужно, изменяя ограничение Autolayout, манипулируякадр непосредственно или используя UIStackView)

class Cell: UITableViewCell {
    var isNew: Bool = false {
        didSet {
            if isNew {
                button.isHidden = true
                leftConstraint.constant = 20
            } else {
                button.isHidden = false
                leftConstraint.constant = 100
            }                    
            self.setNeedsLayout()
        }
    }
    var button: UIButton!
    var label: UILabel!
    var leftConstraint: NSLayoutConstraint!
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        button = UIButton(type: .system)
        button.setTitle("Click", for: .normal)
        self.contentView.addSubview(button)
        button.translatesAutoresizingMaskIntoConstraints = false
        button.widthAnchor.constraint(equalToConstant: 50).isActive = true
        button.heightAnchor.constraint(equalToConstant: 10).isActive = true
        button.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 20).isActive = true
        button.topAnchor.constraint(equalTo: self.topAnchor, constant: 20).isActive = true

        label = UILabel()
        label.text = "Label"
        self.contentView.addSubview(label)
        label.translatesAutoresizingMaskIntoConstraints = false
        label.widthAnchor.constraint(equalToConstant: 200).isActive = true
        label.heightAnchor.constraint(equalToConstant: 20).isActive = true
        label.topAnchor.constraint(equalTo: self.topAnchor, constant: 10).isActive = true
        leftConstraint = label.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 100)
        leftConstraint.isActive = true
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}
0 голосов
/ 09 октября 2018

Вы можете подумать, что вы получаете «свежую» ячейку, но когда ячейка получает повторный цикл , это означает, что он получает повторно используемый .

Это очень легко увидеть, изменив цвет текста базовой ячейки.

Например:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "MyID", for: indexPath) as! MyCustomCell

    if indexPath.row == 3 {
        cell.theLabel.textColor = .red
    }

    return cell
}

Как и следовало ожидать, когда таблицаПри первой загрузке цвет текста изменится для 4-й строки (индексирование строк начинается с нуля).

Однако предположим, что у вас есть 100 строк?При прокрутке ячейки будут повторно использоваться ... и каждый раз, когда исходная 4-я ячейка будет использоваться повторно, она все равно будет иметь красный текст.

Итак, каккак вы уже догадались, вам нужно «сбрасывать» ячейку в исходное расположение / содержимое / цвета / и т. д. каждый раз, когда вы хотите ее использовать:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "MyID", for: indexPath) as! MyCustomCell

    if indexPath.row == 3 {
        cell.theLabel.textColor = .red
    } else {
        cell.theLabel.textColor = .black
    }

    return cell
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...