UITableView загружает только пользовательские ячейки, которые видны на устройстве, и вылетает при добавлении еще одной ячейки - PullRequest
0 голосов
/ 18 апреля 2019

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

При загрузке приложения значение numberOfRowsinSection равно 1 и при каждой новой записионо увеличивается на 1. Если устройство имеет 10 видимых ячеек, оно падает на 11. Если устройство имеет 6 видимых ячеек, оно падает на 7. Приложение неожиданно находит ноль, разворачивая необязательное значение.

Использование советов из вопроса под названием UITableview Не прокручивается? Я пробовал каждую из следующих строк в viewDidLoad и в своей функции:

   self.myTableView.delegate = self

  self.myTableView.autoresizingMask = UIView.AutoresizingMask.flexibleHeight;

  self.myTableView.rowHeight = UITableView.automaticDimension

   self.myTableView.bounces = true;

  self.myTableView.reloadData()

без каких-либо положительныхрезультат.

Вот код:

var enterCounts: Int = 1 

public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return enterCounts
    }

  public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "TextInputCell") as! TextInputTableViewCell

        return cell
    }        


  @IBAction func enter(_ sender: Any) {

    let activeRow = self.enterCounts - 1
    let index = IndexPath(row: activeRow, section: 0)
    let cell: TextInputTableViewCell  = self.myTableView.cellForRow(at: index) as! TextInputTableViewCell


    if cell.myTextField.text == ""  {
         "DO NOTHING"
    } else {

        "DO STUFF"

        enterCounts += 1

        self.myTableView.reloadData()

        let nextIndex = IndexPath(row: activeRow + 1, section: 0)


 "This is the line that finds nil and crashes when row is out of view"

        let nextCell: TextInputTableViewCell = self.myTableView.cellForRow(at: nextIndex) as! TextInputTableViewCell
        nextCell.myTextField.text = ""
        nextCell.myTextField.becomeFirstResponder()
    }

}

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

После 2 ответов код выглядит следующим образом:

    @IBAction func enter(_ sender: Any) {

    let activeRow = self.enterCounts - 1
    let index = IndexPath(row: activeRow, section: 0)
    let cell: TextInputTableViewCell  = self.myTableView.cellForRow(at: index) as! TextInputTableViewCell


    if cell.myTextField.text == ""  {
         "DO NOTHING"
    } else {

        "DO STUFF"

      enterCounts += 1
      let nextIndex = IndexPath(row: activeRow + 1, section: 0) 
      self.myTableView.insertRows(at: [nextIndex], with: .automatic)
      self.myTableView.scrollToRow(at: nextIndex,at: .middle, animated: true)

     //These lines are executed only when I am in visible cells 
     //when a new cell is added it is not ready to become first responder it is skipped and entered text is getting mixed up.
 if let nextCell: TextInputTableViewCell = self.myTableView.cellForRow(at: nextIndex) as? TextInputTableViewCell {
            nextCell.myTextField.text = ""
            nextCell.myTextField.becomeFirstResponder()
           }
    }

}

С кодом выше новые ячейки выглядят чудесно, но textField становится первым респондентом только один раз, для первой ячейкиэто появляется в поле зрения.

Я объявляю свой пользовательский класс ячейки следующим образом:

          @IBOutlet weak var myTextField: UITextField!

 public func configure(text: String?, placeholder: String) {


    myTextField.text = text
  //  myTextField.placeholder = placeholder

    myTextField.accessibilityValue = text
   // myTextField.accessibilityLabel = placeholder

}


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

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

    // Configure the view for the selected state
}

Если я использую textField вне tableView и сохраняю tableView только для отображения моих введенных значений, все просто, но для entryFieldПоследняя ячейка tableView создает проблемы, когда я пытаюсь сделать первый респондент textField новой вставленной ячейки.

Ответы [ 3 ]

0 голосов
/ 18 апреля 2019

Это сбой, потому что яблоко сохраняет только те ячейки в памяти, которые видны. В вашем случае вы обращаетесь к ячейке, которой нет в памяти, и вместо этого вы используете необязательную, которую вы заставляете развернуть, что вызывает сбой.Зная это, вы должны обработать исключение для ячеек, которые не видны, например, bewlow

@IBAction func enter(_ sender: Any) {

let activeRow = self.enterCounts - 1
let index = IndexPath(row: activeRow, section: 0)
let cell: TextInputTableViewCell  = self.myTableView.cellForRow(at: index) as! TextInputTableViewCell


if cell.myTextField.text == ""  {
     "DO NOTHING"
} else {

    "DO STUFF"

    enterCounts += 1

    self.myTableView.reloadData()

    let nextIndex = IndexPath(row: activeRow + 1, section: 0)


 //"This is the line that finds nil and crashes when row is out of view"

   if let nextCell: TextInputTableViewCell = self.myTableView.cellForRow(at: nextIndex) as? TextInputTableViewCell
{
    nextCell.myTextField.text = ""
    nextCell.myTextField.becomeFirstResponder()
}

}

или

, если вы хотите, чтобы ваш респондент первым отвечал в текстовом поле и получил ячейкув памяти путем прокрутки к индексу или вставив его, а затем получить доступ к нему.

0 голосов
/ 20 апреля 2019

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

Я предполагаю, что вам просто нужно текстовое поле в табличном представлении, но это можетработать с другими вещами, также в вашем пользовательском классе, создайте выход для вашего текстового поля, назовите его как хотите, я нахожу это tf, и сделайте это

iboutlet weak var tf: uitextfield!{
didSet{
tf.delegate = self
}}

и создайте переменную замыкания, подобную этой

var textsaved: ((String) -> Void)?

затем добавьте делегат текстового поля в свой класс customcell, как это

extension CustomCell: uitextfielddelegate{ }

, затем в своем расширении напишите:

func textfieldshouldreturn(_ textfield: uitextfield) -> Bool{
tf.resignFirstResponder() 
retrun true }

func textfielddidendediting(_ textfield: uitextfield){
textsaved?(textfield.text!) }

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

var myarr = [String]()

сделать вывод для кнопки ввода и просмотра таблицы

@iboutlet weak var mytableview: uitableView!{
didSet{
mytableview.delegate = self
mytableview.datasource = self }

@iboutlet weak var enterBtn(_ sender: uibutton) {
myarr.append("")
mytableview.reloaddata() }

в количестве строк вернуть myarr.count

в ячейку для строки в

let cell = tableview.dequereuseablecell(withidentifier: "cell", for :indexpath) as! customcell
cell.tf.text = myarr[indexpath.row]
cell.textsaved = { [unowned self] (text) in 
self.myarr.remove(at: indexpath.row)
self.myarr.insert(text, at: indexpath.row)
sel.mytableview.reloaddata()
} return cell }
0 голосов
/ 18 апреля 2019

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

let indexPath = IndexPath(row: ... , section: ...)
tableView.insertRows(at: [indexPath], with: .automatic)

после этого прокрутите до нее

   tableView.scrollToRow(at: indexPath,at: .middle, animated: true) 

наконец, вы можете использовать эту ячейку

let cell = tableView.cellForRow(at: nextIndex) as! YourCustomCellClass
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...