Reputation: 145
So I'm customizing a tableview to hold multiple columns. I want 3 columns, and am customizing the TableViewCell, except I'm at a roadblock.
Right now I have a TableView that is in a ViewController, and the TableView accurately holds one column of data. Here I am changing it to three columns and I get an error about unwrapping an optional nil value.
Here's the important parts of viewcontroller with the tableview (FinishTestController.swift):
var bestRank: [String] = ["1", "2", "3", "4", "5"]
var bestScore: [String] = ["-----", "-----", "-----", "-----", "-----"]
var bestTime: [String] = ["-----", "-----", "-----", "-----", "-----"]
override func viewDidLoad() {
super.viewDidLoad()
addhighscore()
loadhighscores()
self.tableView.registerClass(TableViewCell.self, forCellReuseIdentifier: "cell")
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return bestRank.count;;
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! TableViewCell
cell.column1.text = self.bestRank[indexPath.row]//<-- ERROR points here
cell.column2.text = self.bestScore[indexPath.row]
cell.column2.text = self.bestTime[indexPath.row]
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
println("You selected cell #\(indexPath.row)!")
}
func loadhighscores(){
var result = db.query("SELECT * from EASY_MATH5 ORDER BY Score DESC, Time ASC LIMIT 5", parameters: nil)
println("===============================")
for row in result
{
bestScore[i] = row["Score"]!.asString()
print(bestScore[i])
bestTime[i] = row["Time"]!.asString()
println(bestTime[i])
i++
}
}
Here's my cell:
class TableViewCell: UITableViewCell {
@IBOutlet weak var column1: UILabel!
@IBOutlet weak var column2: UILabel!
@IBOutlet weak var column3: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
And here's the error I get:
fatal error: unexpectedly found nil while unwrapping an Optional value (lldb)
and points to the line that says "cell.column1.text = self.bestRank[indexPath.row]" with a line "Thread 1: EXC_BAD_INSTRUCTION".
Any idea on how to resolve?
Upvotes: 0
Views: 8262
Reputation: 532
Using your code I made minor adjustments which I've noted in the comments with "// nb: " - it works fine now - once those minor points were removed.
Only other change in my code that I did, was the use of "Cell1" instead of "cell" and name of custom cell as "CustomTableViewCell" instead of "TableViewCell", but this is only from personal habit.
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
@IBOutlet var tableView: UITableView!
var bestRank : [String] = ["1", "2", "3", "4", "5"]
var bestScore: [String] = ["-----", "-----", "-----", "-----", "-----"]
var bestTime: [String] = ["-----", "-----", "-----", "-----", "-----"]
// --------------------------------------
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.bestRank.count // nb: use of "self." and no ";;" at end
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell1", forIndexPath: indexPath) as! CustomTableViewCell
cell.column1.text = self.bestRank[indexPath.row]
cell.column2.text = self.bestScore[indexPath.row]
cell.column3.text = self.bestTime[indexPath.row]
return cell
}
// --------------------------------------
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
print("You selected cell #\(indexPath.row)!")
}
// --------------------------------------
override func viewDidLoad() {
super.viewDidLoad()
// nb: Not used: "self.tableView.registerClass(TableViewCell.self, forCellReuseIdentifier: "cell")"
// nb: Datasource + delegate already assigned with tableview in storyboard with click-drag-drop into ViewController. }
CustomCell was done like yours...
class CustomTableViewCell: UITableViewCell {
@IBOutlet var column1: UILabel!
@IBOutlet var column2: UILabel!
@IBOutlet var column3: UILabel!
** Results = No Error ** Simulator showing table as you wanted...
Upvotes: 0
Reputation: 15331
Remove
self.tableView.registerClass(TableViewCell.self, forCellReuseIdentifier: "cell")
From viewDidLoad()
, you don't need to register your UITableViewCell
subclass if you're using prototype cells.
Upvotes: 2
Reputation: 155
You should most likely be using a UICollectionView for this type of behaviour.
With a collection view you will have more control of the layout of each cell.
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UICollectionView_class/
Upvotes: -1