Search code examples
iosswiftuitableviewnsrangeexception

numberOfRowsInSection not overriding Attributes Inspector


In Swift 2, working on a UITableView that will dynamically create cells based on the contents of a dictionary. The dictionary has 38 entries. When I manually set the Table View Section to have 38 rows in the Attributes Inspector, everything works as expected.

However, this isn't ideal, and I'd rather use numberOfRowsInSection to get the count of my dictionary and create rows/cells that way. When the Att Inspector is set to 1, I get an out of bounds error.

Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 1 beyond bounds [0 .. 0]'

Here is my code:

import SwiftyJSON
import UIKit

class OurTableViewController2: UITableViewController {


    @IBOutlet weak var menuButton: UIBarButtonItem!

    var labels = [String: UILabel]()
    var strings = [String]()
    var objects = [[String: String]]()

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.dataSource = self
        tableView.delegate = self

        self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")

        //gets data that will be used for cells
        let urlString = "http://handheldart.org/api/tags/"
        if let url = NSURL(string: urlString) {
            if let data = try? NSData(contentsOfURL: url, options: []) {
                let json = JSON(data: data)
                parseJSON(json)
            }
        }

        //menu button at top left of screen
        if self.revealViewController() != nil {
            menuButton.target = self.revealViewController()
            menuButton.action = "revealToggle:"
            self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
        }

    }

    //creates array 'objects'
    func parseJSON(json: JSON) {
        for result in json.arrayValue {
            let id = result["id"].stringValue
            let tagURL = result["url"].stringValue
            let tagName = result["name"].stringValue
            let obj = ["id": id, "tagURL": tagURL, "tagName": tagName]
            //print (tagName)
            objects.append(obj)
        }

         tableView.reloadData()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    // MARK: - Table view data source

    //create number of rows based on count of objects array
    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        print ("OBJECTS COUNT")
        print (objects.count) //prints 38
        return objects.count
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

var cell:UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("cell")! as UITableViewCell

        let object = objects[indexPath.row]

        cell.textLabel?.text =  object["tagName"]!

        return cell
    }

Any suggestions?


Solution

  • That because you marked your tableview's content property as "Static Cells". You need to set your tableview's content as "Dynamic Prototypes". You can do that from the tableview Attributes Inspector -> Choose "Dynamic Prototypes on the first property "Content".

    enter image description here