使表视图部分迅速扩大

我正在按照这个教程展开和折叠我的表视图部分。 由于这个演示是在swift 2.2中完成的,我已经根据swift 3.0做了所有的更改。 如果条件(currentSectionCells [行] [“isVisible”]),这就给我错误作为“types”NSFastEnumerationIterator.Element“(又名'任何'没有下标成员)'”我被卡在下面的函数。

func getIndicesOfVisibleRows() { visibleRowsPerSection.removeAll() for currentSectionCells in cellDescriptors { var visibleRows = [Int]() for row in 0...((currentSectionCells as! [[String: AnyObject]]).count - 1) { if currentSectionCells[row]["isVisible"] as! Bool == true { visibleRows.append(row) } } visibleRowsPerSection.append(visibleRows) } } 

我已经尝试types铸造它如下

  func getIndicesOfVisibleRows() { visibleRowsPerSection.removeAll() for currentSectionCells in cellDescriptors { var visibleRows = [Int]() for row in 0...((((currentSectionCells) as? NSMutableArray)?.count)! - 1) { let temp = [currentSectionCells][row] as? NSMutableDictionary let temp2 = temp?["isVisible"] as! Bool if temp2 == true { visibleRows.append(row) } } visibleRowsPerSection.append(visibleRows) } } 

但是这让我在运行时崩溃在这条线上“let temp2 = temp?[”isVisible“] as!Bool”Crash说“EXC_BAD_INSTRUCTION”,temp显示为nil。

请帮助家伙。 TIA

表视图委托和数据源

 func numberOfSectionsInTableView(tableView: UITableView) -> Int { if cellDescriptors != nil { return cellDescriptors.count } else { return 0 } } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return visibleRowsPerSection[section].count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let currentCellDescriptor = getCellDescriptorForIndexPath(indexPath: indexPath as NSIndexPath) let cell = tableView.dequeueReusableCell(withIdentifier: currentCellDescriptor["cellIdentifier"] as! String, for: indexPath) as! CustomCell if currentCellDescriptor["cellIdentifier"] as! String == "sectionCellIdentifier" { if let primaryTitle = currentCellDescriptor["secondaryTitle"] { cell.sectionTitleLabel.text = primaryTitle as? String } } else if currentCellDescriptor["cellIdentifier"] as! String == "shortAnswerCell" { cell.questionTitle.text = currentCellDescriptor["primaryTitle"] as? String cell.questionTextView.text = currentCellDescriptor["secondaryTitle"] as? String cell.answerTextView.text = currentCellDescriptor["answerTitle"] as? String } return cell } func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let indexOfTappedRow = visibleRowsPerSection[indexPath.section][indexPath.row] let temp = cellDescriptors[indexPath.section] as? NSArray let temp2 = temp?[indexOfTappedRow ] as? NSDictionary let temp3 = temp2?["isExpandable"] as! Bool if temp3 == true { var shouldExpandAndShowSubRows = false if temp3 == false { // In this case the cell should expand. shouldExpandAndShowSubRows = true } temp2?.setValue(shouldExpandAndShowSubRows, forKey: "isExpanded") for i in (indexOfTappedRow + 1)...(indexOfTappedRow + (temp2?["additionalRows"] as! Int)) { (temp![i] as AnyObject).setValue(shouldExpandAndShowSubRows, forKey: "isVisible") } } getIndicesOfVisibleRows() tblExpandable.reloadSections(NSIndexSet(index: indexPath.section) as IndexSet, with: UITableViewRowAnimation.fade) } 

我也参与了这个教程,并在swift3中成功地完成了它。你的解决scheme在下面给出相应的修改。

  class yourClass: UIViewController { @IBOutlet weak var profileTableView: UITableView! internal var visibleRowsPerSection = [[Int]]() internal var cellDescriptors: NSMutableArray! // VIEW DID LOAD override func viewDidLoad() { super.viewDidLoad() profileTableView.showsVerticalScrollIndicator = false loadProfileControllerData() profileTableSetUp() // Do any additional setup after loading the view. } func loadProfileControllerData(){ if let path = Bundle.main.path(forResource: "CellDescriptor", ofType: "plist") { cellDescriptors = NSMutableArray(contentsOfFile: path) } getIndicesOfVisibleRows() profileTableView.reloadData() } // SHOW PARENT VISIBLE ROWS AND SAVE THERE ROW INDEX IN ARRAY func getIndicesOfVisibleRows() { visibleRowsPerSection.removeAll() for currentSectionCells in cellDescriptors.objectEnumerator().allObjects as! [[[String:Any]]]{ var visibleRows = [Int]() for row in 0..<currentSectionCells.count { if currentSectionCells[row]["isVisible"] as! Bool == true { visibleRows.append(row) } } visibleRowsPerSection.append(visibleRows) print(visibleRowsPerSection) } } // GET REQUIRED OBJECT OF TYPE [String: Any] func getCellDescriptorForIndexPath(indexPath: NSIndexPath) -> [String: Any] { let indexOfVisibleRow = visibleRowsPerSection[indexPath.section][indexPath.row] let cellDescriptorss = cellDescriptors[indexPath.section] as! NSArray let data = cellDescriptorss.object(at: indexOfVisibleRow) as! [String:Any] return data } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } } //---------------------- // EXTENSION TO OUR PROFILE CLASS THAT DETERMINE OUR CLASS CONFIRM 2 IMPORTANT DELEGATES extension profileViewController : UITableViewDelegate,UITableViewDataSource{ //MARK-: TABLE VIEW DELEGATE FUNCTIONS // RETURN NUMBER OF SECTION IN TABLE VIEW public func numberOfSections(in tableView: UITableView) -> Int{ if cellDescriptors.count != 0{ return cellDescriptors.count } else{ return 0 } } // RETURN NUMBER OF ROWS IN EACH SECTION OF TABLE VIEWS public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{ return visibleRowsPerSection[section].count } /* Return object of UITableViewCell that contains table SECTON data and USER profile data */ func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{ let currentCellDescriptor = getCellDescriptorForIndexPath(indexPath: indexPath as NSIndexPath) let menuCell = tableView.dequeueReusableCell(withIdentifier: currentCellDescriptor["cellIdentifier"] as! String, for: indexPath) as! yourCellClass if currentCellDescriptor["cellIdentifier"] as! String == "parent"{ } else if currentCellDescriptor["cellIdentifier"] as! String == "child"{ menuCell.backgroundColor = UIColor.clear } return menuCell } public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath){ let indexOfTappedRow = visibleRowsPerSection[indexPath.section][indexPath.row] let cellDescriptorss = cellDescriptors[indexPath.section] as! NSArray var data = cellDescriptorss.object(at: indexOfTappedRow) as! [String:Any] if data["isExpandable"] as! Bool == true{ var shouldExpandAndShowSubRows = false if data["isExpanded"] as! Bool == true{ shouldExpandAndShowSubRows = false (cellDescriptorss[indexOfTappedRow] as AnyObject).setValue(shouldExpandAndShowSubRows, forKey: "isExpanded") } for i in (indexOfTappedRow + 1)...(indexOfTappedRow + (data["additionalRows"] as! Int)) { (cellDescriptorss[i] as AnyObject).setValue(shouldExpandAndShowSubRows, forKey: "isVisible") } } getIndicesOfVisibleRows() self.profileTableView.reloadSections(NSIndexSet(index: indexPath.section) as IndexSet, with: UITableViewRowAnimation.fade) } 

谢谢你帮助我,我被困在一个点,甚至在你的帮助后,部分不扩大,所以只是在语法上做了一些修改,因为Swift 3.0对于types转换非常具体,因此didSelectRowAt不能正常工作。 这是完整的didSelectRowAt方法。 快乐的编码。

 public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath){ let indexOfTappedRow = visibleRowsPerSection[indexPath.section][indexPath.row] if (cellDescriptors[indexPath.section] as! [[String: AnyObject]])[indexOfTappedRow] ["isExpandable"] as! Bool == true { var shouldExpandAndShowSubRows = false if (cellDescriptors[indexPath.section] as! [[String: AnyObject]])[indexOfTappedRow]["isExpanded"] as! Bool == false { // In this case the cell should expand. shouldExpandAndShowSubRows = true } ((cellDescriptors[indexPath.section] as! NSMutableArray)[indexOfTappedRow] as AnyObject).setValue(shouldExpandAndShowSubRows, forKey: "isExpanded") for i in (indexOfTappedRow + 1)...(indexOfTappedRow + ((cellDescriptors[indexPath.section] as! [[String: AnyObject]])[indexOfTappedRow]["additionalRows"] as! Int)) { ((cellDescriptors[indexPath.section] as! NSMutableArray)[i] as AnyObject).setValue(shouldExpandAndShowSubRows, forKey: "isVisible") } } 

Swift 3/4不使用基于教程的NSMutable数组和基于模型的所有代码。

 class CellsDescriptorModel { private var cellDescriptors: [[[String:Any]]]! private var visibleRowsPerSection : [[Int]] var CellDescriptors : [[[String:Any]]] { get { return cellDescriptors }} var VisibleRowsPerSection : [[Int]] { get { return visibleRowsPerSection }} init(plist:String) { visibleRowsPerSection = [[Int]]() if let url = Bundle.main.url(forResource:plist, withExtension: "plist") { do { let data = try Data(contentsOf:url) cellDescriptors = try PropertyListSerialization.propertyList(from: data, options: [], format: nil) as! [[[String:Any]]] } catch { print(error) } } getIndicesOfVisibleRows() } func getCellDescriptorForIndexPath(indexPath: IndexPath) -> [String: Any] { let indexOfVisibleRow = visibleRowsPerSection[indexPath.section][indexPath.row] return cellDescriptors[indexPath.section][indexOfVisibleRow] } func expandCell(indexPath:IndexPath) { let indexOfTappedRow = visibleRowsPerSection[indexPath.section][indexPath.row] if cellDescriptors[indexPath.section][indexOfTappedRow] ["isExpandable"] as! Bool == true { var shouldExpandAndShowSubRows = false if cellDescriptors[indexPath.section][indexOfTappedRow]["isExpanded"] as! Bool == false { shouldExpandAndShowSubRows = true } cellDescriptors[indexPath.section][indexOfTappedRow]["isExpanded"] = shouldExpandAndShowSubRows for i in (indexOfTappedRow + 1)...(indexOfTappedRow + (cellDescriptors[indexPath.section][indexOfTappedRow]["additionalRows"] as! Int)) { cellDescriptors[indexPath.section][i]["isVisible"] = shouldExpandAndShowSubRows } } else { if cellDescriptors[indexPath.section][indexOfTappedRow]["cellIdentifier"] as! String == "DataPickerTableViewCell" { var indexOfParentCell: Int! for index in (0..<indexOfTappedRow).reversed() { if cellDescriptors[indexPath.section][index]["isExpandable"] as! Bool == true { indexOfParentCell = index break } } cellDescriptors[indexPath.section][indexOfParentCell]["secondaryTitle"] = "" cellDescriptors[indexPath.section][indexOfParentCell]["isExpanded"] = false for i in (indexOfParentCell + 1)...(indexOfParentCell + (cellDescriptors[indexPath.section][indexOfParentCell]["additionalRows"] as! Int)) { cellDescriptors[indexPath.section][i]["isVisible"] = false } } } getIndicesOfVisibleRows() } private func getIndicesOfVisibleRows() { visibleRowsPerSection.removeAll() for currentSectionCells in cellDescriptors { var visibleRows = [Int]() for row in 0..<currentSectionCells.count { if currentSectionCells[row]["isVisible"] as! Bool == true { visibleRows.append(row) } } visibleRowsPerSection.append(visibleRows) } } 

}