(Swift)如何(animation)显示/隐藏单元格基于UITextfieldinput通过重新加载UITableView?

我是一个开始的iOS开发人员,我一直在一个问题上陷入了一段时间。

背景:我有一个单一的视图控制器与tableview。 它拥有4个dynamic的原型单元:原型单元1有一个UITextField和一对标签,原型单元2有一个图像,原型单元3和4只有一个标签。 (注意:原型单元格4是基于对象中的一个数组,并且可以有一个或多个单元格)

在打开屏幕时,只有具有UITextField的第一个单元应该是可见的。 当用户在这个UITextField中input一个数字(最多3位数字)时,必须比较数字以检查它是否是对象数组中的现有数字。 如果这个数字certificate是正确的,则有两件事情必须发生:

  1. 第一个单元格中的标签将需要更改布局(颜色,字体,大小等)。 第一个单元格更改rowHeight。
  2. 其他3个单元将不得不出现并显示与数字对应的数据。

如果编号错误,则不会出现额外的单元格,并且第一个单元格会更新以告知用户它是不正确的。

问题:根据第一个单元格中的numberinput,我正在animation3个单元格出现和消失的方式。 更具体的方法“toggleCellsVisibility”以及它如何与细胞的创build相关联。

我尝试了多种组合:beginUpdates(),endUpdates(),reloadData(),reloadRowsAtIndexPath(),DispatchQueue.main.async {}和UIView.Animate()。 但是我的代码工作的唯一方法是如果我实现下面的toggleCellsVisibility方法,它不给我任何animation选项。

我似乎在创build和重新加载数据方面做了一些错误。 我认为这与在加载屏幕时使用全局variablesindexOfObject和tempObject有关,它们保存虚拟数据,然后在给出正确数字时显示和覆盖实际数据。

总结:当我在第一个单元格中input正确的数字时,是否可以以某种方式插入/创build3个单元格,同时使用这个特定的设置来animation这个变化?

额外:我可以通过不使用heightForRowAtIndexPath来显示/隐藏额外的单元格吗? 如果细胞可以自我大小,会更好。

我select并简化了相关的代码片段:

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! } 

任何帮助将非常感激! 谢谢!

当你的动作完成了(检查input是否匹配任何你想要的),填充你用于tableview的数据源(你应该声明一个空数组作为数据源,并使用它),然后在你的tableview上使用reloadData()。

对于你的单元格的高度,你可以使用tableView.rowHeight = UITableViewAutomaticDimensionhttps://developer.apple.com/library/content/documentation/UserExperience/Conceptual/AutolayoutPG/WorkingwithSelf-SizingTableViewCells.html