2016-10-26 4 views
0

Я начинающий разработчик iOS, и я уже давно застрял в проблеме.(Swift) Как (оживить) показать/скрыть ячейки на основе ввода UITextfield, перезагрузив UITableView?

Фон: У меня есть единый viewcontroller с таблицей. Он содержит 4 динамических ячейки прототипа: prototypecell 1 имеет UITextField и пару ярлыков, prototypecell 2 имеет изображение, prototypecell 3 и 4 имеют только одну метку. (Примечание: прототип ячейки 4 основан на массиве в объекте и может иметь 1 или более ячеек)

При открытии экрана должна быть видна только первая ячейка с UITextField. Когда пользователь вводит число (не более 3 цифр) в этом UITextField, его необходимо сравнить, чтобы проверить, является ли это существующим числом в массиве объектов. Если это число оказывается правильным, 2 вещи должны произойти:

  1. Метки в первой ячейке необходимо изменить расположение (цвет, шрифт, размер, ...). И первая ячейка меняет rowHeight.
  2. Остальные 3 ячейки должны появиться и показать данные, соответствующие номеру.

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

Проблема: У меня возникли проблемы с анимацией того, как 3 ячейки появляются и исчезают в зависимости от номера в первой ячейке. Более конкретно, метод «toggleCellsVisibility» и то, как он относится к созданию ячеек.

Я пробовал несколько комбинаций: beginUpdates(), endUpdates(), reloadData(), reloadRowsAtIndexPath(), DispatchQueue.main.async {} и UIView.Animate(). Но единственный способ, которым работает мой код, - это реализовать метод toggleCellsVisibility, как показано ниже, что не дает мне никаких вариантов анимации.

Кажется, что я делаю что-то неправильно с созданием и перезагрузкой данных. Я думаю, что это связано с использованием глобальных переменных indexOfObject и tempObject, которые содержат фиктивные данные при загрузке экрана и затем отображаются и переопределяются фактическими данными, когда задано правильное число.

Основная информация: Могу ли я каким-либо образом вставить/создать 3 ячейки, когда в первую ячейку вводится правильный номер, а также анимировать это изменение с помощью этой конкретной настройки?

Дополнительная информация: Могу ли я показать/скрыть дополнительные ячейки, не используя heightForRowAtIndexPath? Было бы лучше, если бы клетки могли самостоятельно измеряться.

я выбрал и упрощены соответствующие фрагменты кода:

1) TableView Класс:

class TableViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, updateUITableView { 

var objects: [Object] = [ 
    name: "test1", number: "test2", image: "imageName1", color: UIColor.black, array: ["test3", "test4"], 
    [name: "test1", number: "test2", image: "imageName2", color: UIColor.white, array: ["test3", "test4", "test5"] 
    //... 
] 

var cellsRowHeight = false 

var indexOfObject: Int = 0 
var tempObject = Object[name: "test1", number: "test2", color: UIColor.blue, image: "imageName3", array: ["test3"]] 

@IBOutlet var tableView: UITableView! 

// MARK: - Table view data source 
func numberOfSections(in tableView: UITableView) -> Int { 
    return 1 
} 

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    let numberOfRows = 3 + tempObject.subArray.count 
    return numberOfRows 
} 

//START - Input received from textfield in first cell 
func checkNumberInput(senderCell: SearchInputTableViewCell, number: String) { 
    // step 1: Check if number exists 
    let match = checkNumberMatch(numberInput: number) 

    // step 2: Change lay-out of input cell 
    senderCell.changeLayout(numberMatch: match.0, name: match.1?.name, color: match.1?.color) 

    // step 3: Show/hide cells 
    toggleCellsVisibility(numberMatch: match.0) 
} 

//STEP 1: Check if the number corresponds to an existing number 
func checkNumberMatch(numberInput: String) -> (Bool, Object?) { 
    var returnObject: Object? 
    var tuple = (false, returnObject) 

    for (index, object) in objects.enumerated() where object.number == numberInput { 
     returnObject = object 

     tuple = (true, returnObject) 

     tempObject = object 
     indexOfObject = index 
    } 
    return tuple 
} 

//STEP 3 = !!PROBLEM!! 
func toggleCellsVisibility(numberMatch: Bool) { 
    cellsRowHeight = numberMatch 
    // if/else because of additional future implementation 
    if numberMatch == true { //Cells appear 
     DispatchQueue.main.async { 
      self.tableView?.reloadData() 
     } 

    } else { //Cells disappear 
     DispatchQueue.main.async { 
      self.tableView?.reloadData() 
     } 
    } 
} 

//STEP 4: 
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 
    switch (indexPath.row) { 
    case 0 where !cellsRowHeight: 
     return 187 
    case 0 where cellsRowHeight: 
     return 170 
    case 1 where !cellsRowHeight: 
     return 0 
    case 1 where cellsRowHeight: 
     return 170 
    case 2 where !cellsRowHeight: 
     return 0 
    case 2 where cellsRowHeight: 
     return 54 
    case 3...200 where !cellsRowHeight: 
     return 0 
    case 3...200 where cellsRowHeight: 
     return 44 
    default: 
     return 44 
    } 
} 

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    if indexPath.row == 0 { 
     let cellIdentifier = "InputCell" 
     let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! InputCell 

     cell.delegate = self 

     return cell 
    } 
    else if indexPath.row == 1 { 
     let cellIdentifier = "Cell2" 
     let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! Cell2 

     cell.image?.image = UIImage(named: objects[indexOfObject].image) 

     return cell 
    } 
    else if indexPath.row == 2 { 
     let cellIdentifier = "Cell3" 
     let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! Cell3 

     cell.name?.text = objects[indexOfObject].name 

     return cell 
    } 
    else { 
     let cellIdentifier = "Cell4" 
     let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! Cell4 

     cell.name?.text = objects[indexOfObject].subArray[(indexPath as IndexPath).row - 3] 

     return cell 
    } 
}} 

2) Сотовый Класс:

protocol updateUITableView: class { 
    func checkNumberInput(senderCell: SearchInputTableViewCell, number: String) 
} 

class InputCell: UITableViewCell, UITextFieldDelegate { 

    var delegate: updateUITableView? 

    @IBOutlet var textField: UITextField! 
    @IBOutlet var nameLabel: UILabel! 
    //... and other labels 

    func changeLayout(numberMatch: Bool, name: String?, color: UIColor?) { 
     if numberMatch == true { 
      //lay-out changes to labels 
     } 
     else { 
      //lay-out changes to labels 
     } 
    } 

    //Set maximum character limit in textField and dismiss keyboard when character limit (3) is reached. 
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { 
     let currentCharacterCount = textField.text?.characters.count ?? 0 
     let newLength = currentCharacterCount + string.characters.count - range.length 

     if (newLength == 3) { 
      textField.text = (textField.text! as NSString).replacingCharacters(in: range, with: string) 

      //Get text from textField 
      let numberInput: String? = textField.text! //Get number if 3 characters entered 
      if numberInput != nil { 
       delegate?.checkNumberInput(senderCell: self, number: numberInput!) 
      } 
      textField.resignFirstResponder() 

      if (range.length + range.location > currentCharacterCount) { 
       return false 
      } else { 
       return true 
      } 
     } 
     return true 
    } 
} 

class Cell2: UITableViewCell { 
    @IBOutlet var image: UIImageView! 
} 

class Cell3: UITableViewCell { 
    @IBOutlet var name: UILabel! 
} 

class Cell4: UITableViewCell { 
    @IBOutlet var name: UILabel! 
} 

Любая помощь будет очень ценится! Спасибо!

+0

Почему у вас всегда есть три ячейки? Вставьте дополнительные ячейки по мере необходимости (убедитесь, что numberOfRowsInSection всегда возвращает правильный номер) – Paulw11

+0

@ Paulw11 На экране всегда есть как минимум 1 ячейка (inputCell), но при правильном вводе добавляются дополнительные 3 ячейки: прототип ячейки 2 имеет 1 строка с изображением, прототип ячейки 3 имеет 1 строку с именем, а ячейка 4 прототипа имеет неизвестное количество строк на основе subArray в объектах. И все они должны иметь возможность изменять высоту в зависимости от ввода. Таким образом, numberOfRowsInSection будет меняться между: 1) 1 ячейкой (inputcell) и 2) 1 ячейкой (inputcell) + 2 (две ячейки, каждая из которых имеет 1 строку) + число, основанное на subarray в объекте Итак, как бы я мог динамически переключаться между эти? – Aovib

ответ

0

Когда ваше действие завершено (убедитесь, что вход соответствует всем вашим потребностям), заполните источник данных, который вы используете для своего табличного представления (вы должны объявить пустой массив объектов, которые хотите использовать в качестве источника данных, и использовать это), затем используйте reloadData() в вашем представлении таблицы.

Для высоты ваших клеток, вы можете использовать tableView.rowHeight = UITableViewAutomaticDimension (https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/AutolayoutPG/WorkingwithSelf-SizingTableViewCells.html)

 Смежные вопросы

  • Нет связанных вопросов^_^