首页 > 解决方案 > 致命错误:追加数组时数组索引超出范围

问题描述

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

但是,当我试图模拟这一点时,我在 'cell.textData?.text = section[indexPath.row] 上得到了一个致命数组!字符串',我不知道为什么?

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

}

标签: arraysswiftuitableview

解决方案


错误很明显。

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

markschemeRows = text.components(separatedBy: " ")

然后您还必须从而markschemeRows不是从section[indexPath.row]in获取项目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
}

你的代码很麻烦。例如sectionNames并且markschemeRows很明显。[String]为什么将数组声明为[Any]?这是斯威夫特。注意类型NSArray并且根本不要像在 Swift 中那样使用 Foundation 集合类型。再次照顾类型


推荐阅读