Я начинающий разработчик iOS, и я уже давно застрял в проблеме.(Swift) Как (оживить) показать/скрыть ячейки на основе ввода UITextfield, перезагрузив UITableView?
Фон: У меня есть единый viewcontroller с таблицей. Он содержит 4 динамических ячейки прототипа: prototypecell 1 имеет UITextField и пару ярлыков, prototypecell 2 имеет изображение, prototypecell 3 и 4 имеют только одну метку. (Примечание: прототип ячейки 4 основан на массиве в объекте и может иметь 1 или более ячеек)
При открытии экрана должна быть видна только первая ячейка с UITextField. Когда пользователь вводит число (не более 3 цифр) в этом UITextField, его необходимо сравнить, чтобы проверить, является ли это существующим числом в массиве объектов. Если это число оказывается правильным, 2 вещи должны произойти:
- Метки в первой ячейке необходимо изменить расположение (цвет, шрифт, размер, ...). И первая ячейка меняет rowHeight.
- Остальные 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!
}
Любая помощь будет очень ценится! Спасибо!
Почему у вас всегда есть три ячейки? Вставьте дополнительные ячейки по мере необходимости (убедитесь, что numberOfRowsInSection всегда возвращает правильный номер) – Paulw11
@ Paulw11 На экране всегда есть как минимум 1 ячейка (inputCell), но при правильном вводе добавляются дополнительные 3 ячейки: прототип ячейки 2 имеет 1 строка с изображением, прототип ячейки 3 имеет 1 строку с именем, а ячейка 4 прототипа имеет неизвестное количество строк на основе subArray в объектах. И все они должны иметь возможность изменять высоту в зависимости от ввода. Таким образом, numberOfRowsInSection будет меняться между: 1) 1 ячейкой (inputcell) и 2) 1 ячейкой (inputcell) + 2 (две ячейки, каждая из которых имеет 1 строку) + число, основанное на subarray в объекте Итак, как бы я мог динамически переключаться между эти? – Aovib