Когда я изменяю цвет текста UITextField внутри UITableView, этот цвет применяется к другому полю UIText при прокрутке - PullRequest
1 голос
/ 30 марта 2020

Я действительно не понимаю, почему это происходит. Я изменяю цвет текста UITextField, который находится внутри UITableView, если текст изменился, но когда я прокручиваю вниз или вверх tableView, другие UITextFields меняют цвет текста. Как решить эту проблему?

Вот мой код и скриншот проблемы:

import Foundation
import UIKit

private let reuseIdentifier = "ApcGenericCell"
private let portIdentifier = "ApcPortCell"
private let addressIdentifier = "ApcAddressCell"

class MyViewController: UIViewController {

    private var tableView: UITableView!

    private var bottomConstraint: NSLayoutConstraint!
    private var newBottomConstraint: NSLayoutConstraint!

    var apc = [Apc]()

    override func viewDidLoad() {
        super.viewDidLoad()

        // configure the table view for the left menu
        configureTableView()
    }

    private func configureTableView() {
        tableView = UITableView()
        tableView.translatesAutoresizingMaskIntoConstraints = false
        tableView.delegate = self
        tableView.dataSource = self
        tableView.rowHeight = 60

        tableView.register(UINib(nibName: "ApcGeneric", bundle: nil), forCellReuseIdentifier: reuseIdentifier)
        tableView.register(UINib(nibName: "ApcPortAt", bundle: nil), forCellReuseIdentifier: portIdentifier)
        tableView.register(UINib(nibName: "ApcIpAddress", bundle: nil), forCellReuseIdentifier: addressIdentifier)
        self.view.addSubview(tableView)
        tableView.backgroundColor = .clear

        tableView.topAnchor.constraint(equalTo: view.topAnchor, constant: view.frame.height / 8).isActive = true
        tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: view.frame.width / 8).isActive = true
        tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -(view.frame.width / 8)).isActive = true
        bottomConstraint = tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -(view.frame.height / 8))
        bottomConstraint.isActive = true

        tableView.alwaysBounceVertical = false
        tableView.tableFooterView = UIView(frame: .zero)

        // register for notifications when the keyboard appears and disappears:
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(note:)), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(note:)), name: UIResponder.keyboardWillHideNotification, object: nil)

        NotificationCenter.default.addObserver(self, selector: #selector(receivedMessage), name: Notification.Name("ReceivedMessage"), object: nil)

        apc = ApcSection.emptySection()
        self.tableView.reloadData()
    }

    @objc func receivedMessage() {
      DispatchQueue.global(qos: .default).async {
        ApcSection.fetchData(map: self.apcConfig, { (apcResult) in
          self.apc = apcResult

          DispatchQueue.main.async {
              self.tableView.reloadData()
          }
       })
      }
    }

    // Handle keyboard frame changes here.
    // Use the CGRect stored in the notification to determine what part of the screen the keyboard will cover.
    // Adjust our table view's bottomAnchor so that the table view content avoids the part of the screen covered by the keyboard
    @objc func keyboardWillShow(note: NSNotification) {
        // read the CGRect from the notification (if any)
        if let newFrame = (note.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
            if bottomConstraint.isActive {
                bottomConstraint.isActive = false
                newBottomConstraint = tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -newFrame.height)
                newBottomConstraint.isActive = true
                tableView.updateConstraints()
            }
        }
    }

    // User dismiss the keyboard
    @objc func keyboardWillHide(note: NSNotification) {
        newBottomConstraint.isActive = false
        bottomConstraint.isActive = true
        tableView.updateConstraints()
    }

    @objc func textHasChanged(sender: UITextField) {
        let cell = sender.superview?.superview as! UITableViewCell
        let indexPath = tableView.indexPath(for: cell)

        if let index = indexPath?.row {

            if let _ = apc[index] {
                // change textColor if the value has been changed
              if sender.text != apc[index]!) {
                    sender.textColor = .systemRed
                } else {
                    sender.textColor = .myBlue
                }
            }
        }
    }
}

extension MyViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return apc.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if indexPath.row == 0 {
            let cell = tableView.dequeueReusableCell(withIdentifier: portIdentifier, for: indexPath) as! ApcPortAt
            cell.selectionStyle = .none
            return cell
        } else if indexPath.row == 7 || indexPath.row == 9 {
            let cell = tableView.dequeueReusableCell(withIdentifier: addressIdentifier, for: indexPath) as! ApcIpAddress
            cell.selectionStyle = .none
            return cell
        } else {
            let cell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifier, for: indexPath) as! ApcGeneric
            cell.value.text = apc[indexPath.row]
            cell.value.delegate = self
            cell.value.addTarget(self, action: #selector(textHasChanged(sender:)), for: .editingChanged)
            cell.selectionStyle = .none
            return cell
        }
    }
}

Обычный вид

Редактирование

Прокрутите вниз после редактирования

Вернуться к началу

Ответы [ 2 ]

2 голосов
/ 30 марта 2020

UITablView reusable В UITableView dequeueReusableCell - каждый UITableViewCell будет многократно использоваться с различными данными (изображением).
В вашем случае при прокрутке ячейка в IndexPath (строка: x, раздел : 0) была повторно использована другой ячейкой, отображаемой вверху. Пример: ячейка с красным текстом -> эта ячейка х имеет красный текст, потому что вы не сбросили ей цвет текста
Решение:

let cell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifier, for: indexPath) as! ApcGeneric
    cell.value.text = apc[indexPath.row]
    if index == selectedIndex { // condition to red text
        cell.value.textColor = .systemRed
    } else {
        cell.value.textColor = .myBlue
    }
    cell.value.delegate = self
    cell.value.addTarget(self, action: #selector(textHasChanged(sender:)), for: .editingChanged)
    cell.selectionStyle = .none
    return cell
2 голосов
/ 30 марта 2020

У вас есть 2 возможных решения 1. Примените изменения в cellForRowAt делегата UITableViewDataSource. 2. Подкласс UITableViewCell и переопределите prepareForReuse (), в котором вы можете делать свои обновления. И не забудьте зарегистрировать подкласс ячейки в табличном представлении. Я считаю решение № 1 намного проще

...