Can't set PFTableViewCell imageView? - ios

I'm trying to display an icon for each PFTableViewCell based on the imageView property which doesn't work. The code I'm using is below which throws the follow error, "fatal error: unexpectedly found nil while unwrapping an Optional value".
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath, object: PFObject) -> PFTableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("Cell") as! i!
if cell == nil {
cell = PFTableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell")
}
cell.textLabel?.text = "Some Label"
cell.detailTextLabel?.text = "Another label"
cell.imageView.image = UIImage(named: "icon.png")
return cell
}

I had the same issue. Your crash is linked to the imageView being nil.
I guess this is a bug with PFTableViewCell: it does not "see" the standard imageView from the "Basic" style, and cannot create the corresponding PFImageView (I opened an issue with ParseUI).
Generally speaking, it's better to set your line like so:
cell.imageview?.image
then you won't have the crash.
You won't have the image either, but that's because of Parse's PFTableViewCell ...
If you want your code to work, you need to create a custom cell, with an imageView that you need to set as a PFImageView. This way, there will indeed be an imageView, and the whole PFTableViewCell file loading works perfectly.

Related

Cannot assign value of type 'UIColor' to type 'String?'

I am building a Sidebar with Swift.
And I got this error in this code:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell:UITableViewCell! = tableView.dequeueReusableCellWithIdentifier("cell")! as UITableViewCell
if cell == nil{
cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell")
cell!.backgroundColor = UIColor.clearColor()
cell!.textLabel!.text = UIColor.darkTextColor()
}
// Configure the cell...
return cell
}
So there actually is someone on this platform that has the same problem. In the solution they said I have to add a ! behind UIColor.darkTextColor() but if I do that there is another error that I have to delete !
The error is at the line:
cell!.textLabel!
Do you guys know what's going on?
The error is due to this code:
cell!.textLabel!.text = UIColor.darkTextColor()
You are assigning UIColor to a property that expects to be a String (text property of UILabel).
I think you are probably looking to change the text color, if so you need to change the code like:
cell!.textLabel!.textColor = UIColor.darkTextColor()
The problem is you're trying to assign a UIColor to a String. You want to use the textColor property on the cell's textLabel instead, like so:
cell.textLabel?.textColor = UIColor.darkTextColor()
Also note that you have a reusable cell identifier mismatch ("Cell" for newly created ones, "cell" for fetching them).
However, there are bigger issues here.
You really shouldn't be littering about crash operators (!) in order to dismiss compiler errors. Sure, it may be completely 'safe' now (as you do an == nil check) – but it just encourages the future use of them in places where they really shouldn't ever be used. They can also be pretty dangerous for future code refactorings.
I would recommend you re-write your code to take advantage of the nil-coalescing operator (??). You can use this to attempt to get a re-useable cell. If that fails, then you can substitute in a newly created one instead. You can also use an auto-executing closure ({...}()) in order to do some common cell setup.
For example:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// attempt to get a reusable cell – create one otherwise
let cell = tableView.dequeueReusableCellWithIdentifier("foo") ?? {
// create new cell
let cell = UITableViewCell(style: .Default, reuseIdentifier: "foo")
// do setup for common properties
cell.backgroundColor = UIColor.redColor()
cell.selectionStyle = .None
// assign the newly created cell to the cell property in the parent scope
return cell
}()
// do setup for individual cells
if indexPath.row % 2 == 0 {
cell.textLabel?.text = "foo"
cell.textLabel?.textColor = UIColor.blueColor()
} else {
cell.textLabel?.text = "bar"
cell.textLabel?.textColor = UIColor.greenColor()
}
return cell
}
Now it's easy to spot whether a ! belongs in your code or not. It ... er doesn't.
Don't trust anyone who recommends adding extra crash operators to your code in order to solve your problems. It just becomes a source of more problems.

Set PFQueryTableViewCell imageView as a local image

[Developing for iOS using Swift]
I am pulling data from Parse and populating a PFQueryTableView with it, and based on one of the values of the PFObjects that I am using to populate the tableView, I would like to set the imageView of the cell to an image stored locally in my Xcode images.xcassets.
This is my code:
// Set cells for each row of table
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath, object: PFObject?) -> PFTableViewCell? {
var cell = tableView.dequeueReusableCellWithIdentifier("Cell") as! PFTableViewCell!
if cell == nil {
cell = PFTableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "Cell")
}
// Set image as read/unread
if let readStatus = object!["readStatus"] as? String {
if readStatus == "unread" {
cell.imageView?.image = UIImage(named: "unreadImage")
} else if readStatus == "read" {
cell.imageView?.image = UIImage(named: "readImage")
}
}
return cell
}
But it does not set the image...
If I change this line with a ! after imageView (like so): cell.imageView!.image = UIImage(named: "readImage")
I get the error:
fatal error: unexpectedly found nil while unwrapping an Optional value
So how can I set the cell's image based on a Parse value (but I want the image to be a local image)
Something is wrong with your cell object. First of all, you don't need the ! mark at the end. You should have it like this:
let cell = tableView.dequeueReusableCellWithIdentifier("Cell") as! PFTableViewCell
In Xcode 6.3 and Swift 1.2 your next line would not compile because you are checking for nil something that cannot be nil - you are force unwrapping the cell so it is no more an optional and you don't need to check for nil.
So remove the if cell == nil lines and see if your cell is set up correctly in IB (check if you've set the identifier).

Overriding UITableView in Parse with Swift

All,
In swift while using Parse as my backend, I have created a class which inherits from PFQueryTableViewController. I see my data going into a tableview - thats fine.
I am trying to customise my cells a bit, and I overriding CellForRowAtIndexPath - like below :
override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!, object: PFObject!) -> PFTableViewCell!
{
var cellIdentifier = "eventCell"
var cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier) as? PFTableViewCell
if cell == nil {
cell = PFTableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: cellIdentifier)
}
// configure cell
var CellTitle = object.objectForKey("Title") as String
cell?.textLabel = CellTitle
}
}
As the object using comes back as [AnyObject] in swift, I have created a variable and I have casted it to a string. And then I am trying to show that string in Cell.textlabel.
I am getting the error : Cannot assign to the result of this expression.
Can anyone please show me the right direction on this.
I think the problem is that you're attempting to assign a String directly to cell?.textLabel UILabel. Instead try changing this line:
cell?.textLabel = CellTitle
to this
cell.textLabel?.text = CellTitle
so you're setting the text property of the UILabel instead.

Customer Cell returns nil when unwrapping an Optional Value

I have a custom table view cell. In the story board, I have implemented a UILabel and a UIButton. I want to give the label a different value everytime it is reused. The storyboard connections are good. If I use cell.textLabel.text = episodeTitle then that works, but if I set the text property of my UILabel then I get the error
fatal error: unexpectedly found nil while unwrapping an Optional value
I have tried registering a class but that doesn't work. Not sure what to do anymore. There are tons of similar posts on SO but none helped.
This is my cellForRowAtIndexPath:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
//tableView.registerClass(episodeCell.self, forCellReuseIdentifier: "episode")
var cell = tableView.dequeueReusableCellWithIdentifier("episode", forIndexPath: indexPath) as episodeCell
cell = episodeCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "episode")
let episode: MWFeedItem? = episodesToDisplay.objectAtIndex(indexPath.row) as? MWFeedItem
if episode != nil {
//process the episode
var episodeTitle: NSString = episode?.title as String!
//cell.textLabel.text = episodeTitle
cell.episodeTitle.text = episodeTitle
}
return cell
}
and this is my custom cell:
class episodeCell: UITableViewCell {
var progress: Float?
#IBOutlet weak var episodeTitle: UILabel!
}
The error is here:
var cell = tableView.dequeueReusableCellWithIdentifier("episode", forIndexPath: indexPath) as episodeCell
cell = episodeCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "episode")
you dequeue a cell and assign to the cell variable, and next you replace that instance with a brand new one. Remove this line:
cell = episodeCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "episode")

EXC_BAD_INSTRUCTION breakpoint when starting app xCode

I have a tableview in my app and when I start my app it crashes on the following function.
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
// Configure the cell...
let cellId: NSString = "Cell"
var cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier(cellId) as UITableViewCell
}
It crashes on the line of var cell
It gives the following error:
I can't figure out what's wrong with my code.
The whole function:
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
// Configure the cell...
let cellId: NSString = "Cell"
var cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier(cellId) as UITableViewCell
let data: NSManagedObject = mylist[ip.row] as NSManagedObject
cell.textLabel.text = data.valueForKeyPath("voornaam") as String
cell.detailTextLabel.text = data.valueForKeyPath("achternaam") as String
return cell
}
EDIT:
What I got now:(Still gives the same error)
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell? {
// Configure the cell...
let cellId: NSString = "Cell"
var cell: UITableViewCell? = tableView?.dequeueReusableCellWithIdentifier(cellId) as? UITableViewCell
if cell == nil {
cell = UITableViewCell(style: .Subtitle, reuseIdentifier: cellId)
}
let data: NSManagedObject = mylist[indexPath.row] as NSManagedObject
cell!.textLabel.text = data.valueForKey("voornaam") as String
cell!.detailTextLabel.text = data.valueForKey("achternaam") as String
//cell!.textLabel.text = "Hoi"
return cell
}
This is happening because the as operator is defined to cast an object to a given type and crash if the conversion fails. In this case, the call to dequeue returns nil the first time you call it. You need to use the as? operator, which will attempt to cast the given object to a type, and return an optional that has a value only if the conversion succeeded:
var cell: UITableViewCell? = tableView.dequeueReusableCellWithIdentifier(cellId) as? UITableViewCell
if cell == nil {
cell = UITableViewCell(style: .Subtitle, reuseIdentifier: cellId)
}
...
Because cell is now an optional value, use cell! when you want to call methods on it to force-unwrap the UITableViewCell inside it.
Additionally, your code had a second problem: it never created a fresh cell. dequeue will return nil the first time it's called on your table view. You need to instantiate a new UITableViewCell as in my code sample and then return it from the cellFor... method. The table view will then save the cell and return it on future calls to dequeue.
First off, why are you doing an optional binding on line if let ip = indexPath? This argument is not optional and you don't need to do optional binding or unwrap it. But this shouldn't cause your code to crash.
Remove your let data line and assign literal strings to your cells and see if it still crashes.
May I suggest that you check to see if you set the tableview's delegates? I made that mistake once in the flurry of setting everything else up.
Perhaps it is too late but I like to share my experience. I had similar error as I copied the entire code from another project. So I think the variables and functions won't be recognised so I had to drag them (cntr+drag) then it is solved.
Sorry if I couldn't explain better. I am new this.

Resources