swift2 使表视图节快速展开

wn9m85ua  于 2022-11-06  发布在  Swift
关注(0)|答案(3)|浏览(206)

我正在按照this教程来展开和折叠我的表视图部分。由于此演示是在swift 2.2中完成的,我已经根据swift 3.0进行了所有更改。我在以下函数中遇到了if条件(currentSectionCells[row][“isVisible”]),它给我的错误是“Type 'NSFastEnumerationIterator.Element'(aka 'Any' has no subscript members)'”。

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

我已经尝试过如下类型转换

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 temp 2 = temp?[“isVisible”] as!Bool”这一行上导致崩溃,崩溃显示为“EXC_BAD_INSTRUCTION”,并且temp显示为nil。
请帮帮伙计们。
表视图委托和数据源

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)
}
q35jwt9p

q35jwt9p1#

我也做了那个教程,并在swift3中成功地完成了它。下面给出了您的解决方案,请进行相应的修改。

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)

    }
kzmpq1sx

kzmpq1sx2#

谢谢你的帮助,我被困在一个地方,即使在你的帮助下,这些部分也没有扩展,所以我只是在语法上做了一些修改,因为Swift 3.0对类型转换非常具体,因此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")
        }

    }
qyuhtwio

qyuhtwio3#

Swift 3/4没有使用NSMutable数组的基础教程和所有的代码都 Package 在一个模型中。

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

}

相关问题