【问题标题】:Fatal error: Array index out of range when appending array致命错误:追加数组时数组索引超出范围
【发布时间】:2019-05-28 21:08:22
【问题描述】:

我目前有一个要附加选项的数组。它们显示在一个包含 3 个部分的表格中。前 2 部分各有 1 行,但第三部分的行数可变,具体取决于附加到数组的内容。我基本上采用了初始数组的第三个组件(allAlbums[0].markscheme)并将其分解以在数组中创建多个新项目。

但是,当我尝试对此进行模拟时,我在 'cell.textData?.text = section[indexPath.row] as! 上得到了一个致命数组! String',我不知道为什么?

final class CaseViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

@IBOutlet var titleText: UILabel!
@IBOutlet var tableView: UITableView!

private var allAlbums = [Case]()

let kHeaderSectionTag: Int = 6900;

var expandedSectionHeaderNumber: Int = -1
var expandedSectionHeader: UITableViewHeaderFooterView!
var sectionItems: Array<Any> = []
var sectionNames: Array<Any> = []
var markschemeRows: Array<Any> = []

override func viewDidLoad() {
    super.viewDidLoad()

    allAlbums = LibraryAPI.shared.getCases()

    // Filter the main array to match a single case
    allAlbums = allAlbums.filter { $0.title == title}

    // Get data to fill in to table
    sectionNames = [ "Trainee Information", "Patient Information", "Examiner Information" ];
    sectionItems = [ [allAlbums[0].doctor], [allAlbums[0].patient], [allAlbums[0].markscheme]]

    let text = allAlbums[0].markscheme
    markschemeRows = text.components(separatedBy: " ")

    sectionItems.append(contentsOf: markschemeRows)

    // Autoresize rows
    tableView.rowHeight = UITableView.automaticDimension
    tableView.estimatedRowHeight = 500

    // Remove excess row seperators
    tableView.tableFooterView = UIView()
    tableView.separatorColor = UIColor.clear

    titleText.text = title


}

func numberOfSections(in tableView: UITableView) -> Int {
    return 3
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if (self.expandedSectionHeaderNumber == section) {

        // Header section
        let header = self.sectionNames[section] as! String

        // If markscheme, create the markscheme format
        if (header == "Examiner Information")
        {
            print(self.markschemeRows.count)
            return self.markschemeRows.count
        }
        else
        {
            let arrayOfItems = self.sectionItems[section] as! NSArray
            print(arrayOfItems.count)
            return arrayOfItems.count
        }


    } else {
        return 0;
    }
}


func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    if (self.sectionNames.count != 0) {
        return self.sectionNames[section] as? String
    }
    return ""
}

func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return 44.0;
}

func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat{
    return 0;
}

func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
    //recast your view as a UITableViewHeaderFooterView
    let header: UITableViewHeaderFooterView = view as! UITableViewHeaderFooterView
    header.contentView.backgroundColor = UIColor.darkGray
    header.textLabel?.textColor = UIColor.white

    if let viewWithTag = self.view.viewWithTag(kHeaderSectionTag + section) {
        viewWithTag.removeFromSuperview()
    }
    let headerFrame = self.view.frame.size
    let theImageView = UIImageView(frame: CGRect(x: headerFrame.width - 32, y: 13, width: 18, height: 18));
    theImageView.image = UIImage(named: "Chevron-Dn-Wht")
    theImageView.tag = kHeaderSectionTag + section
    header.addSubview(theImageView)

    // make headers touchable
    header.tag = section
    let headerTapGesture = UITapGestureRecognizer()
    headerTapGesture.addTarget(self, action: #selector(CaseViewController.sectionHeaderWasTouched(_:)))
    header.addGestureRecognizer(headerTapGesture)
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "tableCell", for: indexPath) as! CustomTableCell
    let section = self.sectionItems[indexPath.section] as! NSArray

    cell.textLabel?.textColor = UIColor.black

    cell.textData?.text = section[indexPath.row] as! String

    return cell
}

func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
    tableView.deselectRow(at: indexPath, animated: true)
}

// MARK: - Expand / Collapse Methods

@objc func sectionHeaderWasTouched(_ sender: UITapGestureRecognizer) {
    let headerView = sender.view as! UITableViewHeaderFooterView
    let section    = headerView.tag
    let eImageView = headerView.viewWithTag(kHeaderSectionTag + section) as? UIImageView

    if (self.expandedSectionHeaderNumber == -1) {
        self.expandedSectionHeaderNumber = section
        tableViewExpandSection(section, imageView: eImageView!)
    } else {
        if (self.expandedSectionHeaderNumber == section) {
            tableViewCollapeSection(section, imageView: eImageView!)
        } else {
            let cImageView = self.view.viewWithTag(kHeaderSectionTag + self.expandedSectionHeaderNumber) as? UIImageView
            tableViewCollapeSection(self.expandedSectionHeaderNumber, imageView: cImageView!)
            tableViewExpandSection(section, imageView: eImageView!)
        }
    }
}

func tableViewCollapeSection(_ section: Int, imageView: UIImageView) {
    let sectionData = self.sectionItems[section] as! NSArray

    self.expandedSectionHeaderNumber = -1;
    if (sectionData.count == 0) {
        return;
    } else {
        UIView.animate(withDuration: 0.4, animations: {
            imageView.transform = CGAffineTransform(rotationAngle: (0.0 * CGFloat(Double.pi)) / 180.0)
        })
        var indexesPath = [IndexPath]()
        for i in 0 ..< sectionData.count {
            let index = IndexPath(row: i, section: section)
            indexesPath.append(index)
        }
        self.tableView!.beginUpdates()
        self.tableView!.deleteRows(at: indexesPath, with: UITableView.RowAnimation.fade)
        self.tableView!.endUpdates()
    }
}

func tableViewExpandSection(_ section: Int, imageView: UIImageView) {
    let sectionData = self.sectionItems[section] as! NSArray

    if (sectionData.count == 0) {
        self.expandedSectionHeaderNumber = -1;
        return;
    } else {
        UIView.animate(withDuration: 0.4, animations: {
            imageView.transform = CGAffineTransform(rotationAngle: (180.0 * CGFloat(Double.pi)) / 180.0)
        })
        var indexesPath = [IndexPath]()

        // Header section
        let header = self.sectionNames[section] as! String

        // If markscheme, create the markscheme format
        if (header == "Examiner Information")
        {
            for i in 0 ..< markschemeRows.count {
                let index = IndexPath(row: i, section: section)
                indexesPath.append(index)
            }
        }
        else
        {
            for i in 0 ..< sectionData.count {
                let index = IndexPath(row: i, section: section)
                indexesPath.append(index)
            }
        }
        self.expandedSectionHeaderNumber = section
        self.tableView!.beginUpdates()
        self.tableView!.insertRows(at: indexesPath, with: UITableView.RowAnimation.fade)
        self.tableView!.endUpdates()
    }
}

}

【问题讨论】:

    标签: arrays swift uitableview


    【解决方案1】:

    错误很明显。

    numberOfRows 中,您为第 2 部分返回 markschemeRows.count,这是该行中分隔项目的数量

    markschemeRows = text.components(separatedBy: " ")
    

    那么你还必须从markschemeRows而不是section[indexPath.row]中的cellForRow获取项目

    var markschemeRows = [String]()
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "tableCell", for: indexPath) as! CustomTableCell
        let section = self.sectionItems[indexPath.section] as! NSArray
    
        cell.textLabel?.textColor = UIColor.black
        if indexPath.section == 2 {
            cell.textData?.text = markschemeRows[indexPath.row]
        } else {
            cell.textData?.text = section[indexPath.row] as! String
        }
    
        return cell
    }
    

    您的代码相当繁琐。例如sectionNamesmarkschemeRows 显然是[String]。为什么将数组声明为[Any]?这是斯威夫特。 注意类型。并且根本不要在 Swift 中使用像 NSArray 这样的 Foundation 集合类型。再次注意类型

    【讨论】:

    • 太棒了!谢谢!抱歉,我只是在学习,所以我正在整理代码 - 感谢您指出这一点:)
    猜你喜欢
    • 2017-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多