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.
Related
I am converting an app from objective-c to swift. I did not write the objective c code. One of the functions which code is as below...
func tableView (tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cellIdentifier: String = "Cell"
var cell: ListCell? = tableView.dequeueReusableCellWithIdentifier(cellIdentifier)!
And theres more code in the function but i don't think it is relevant. When I run the app, I get an error: "nil found while unwrapping an optional" at the line where I create the variable cell. The error is occurring because I am trying to convert a UITableViewCell to ListCell type. And the conversion is occurring and returning nil. I need to have this line in the code because it is there in the objective-c version of the app.
Is there any way I can get around this and convert a UITableViewCell to ListCell without the conversion failing and returning nil?
Here is the declaration of the ListCell class...
#interface ListCell : UITableViewCell {
//code
}
I did not convert the ListCell class to swift, and instead use a bridging header. Also ListCell is a subclass of UITableViewCell, so why is the conversion not working.
There are two ways you can use dequeueReusableCellWithIdentifier - The most common "modern" way is to have registered the reuse identifier and specified a custom class for your cell in your storyboard. You can also use the UITableView method registerClass:forCellReuseIdentifier to do the same thing programatically.
tableview.registerClass(ListCell.self, forCellReuseIdentifier:"Cell")
In this case you would say
var cell=tableview.dequeueReusableCellWithIdentifier(cellIdentifier) as! ListCell
You can use a forced downcast because you know that the dequeue operation will return a cell of the appropriate type (and if not then you have a problem and throwing an exception is good so you can debug it).
The "old" way was not to register a class and deal with the fact that dequeueReusableCellWithIdentifier may return nil - In this case you need to allocate a new cell yourself;
var cell:Listcell
if let reuseCell = tableview.dequeueReusableCellWithIdentifier(cellIdentifier) as? ListCell {
cell=reuseCell
} else {
cell=ListCell(style: .Default, reuseIdentifier: cellIdentifier)
}
// Now you can configure cell...
Try this, it should work fine.
func tableView (tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cellIdentifier: String = "Cell"
var cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier) as! ListCell
You should use this version:
let cell = tableView.dequeueReusableCellWithIdentifier("Cell",
forIndexPath: indexPath) as! ListCell
The dequeue method version with index path never returns nil (creates new cells automatically, when needed).
The force cast as! either succeeds with a non-optional value, or crashes the app (in this case if the cell was not actually ListCell).
it should be
var cell: ListCell? = tableView.dequeueReusableCellWithIdentifier(cellIdentifier) as! ListCell
I am trying to create a database-based application for iOS and I am, more or less, forced to use Xcode 6.2 Beta 3, because I started the project with 6.2 and run iOS 8.2 on my testdevice. I have by the way figured out that the beta forces me to use the standard keypad, instead of decimal pad, otherwise the app stops working.
I canĀ“t figure out what is wrong. And when I try to comment the function out something is still wrong in this file. Are there any missing connections between the VC-swift-file, tableVC-swift-file and datamodel-file?
I changed the name of the entity list once, and then changed back, because of another error I had before. But after I did it seems like the debug area doesnt catch the data I try to save to the database either...
The error says "Bound value in a conditional binding must be of Optional type"
Here is the code that is marked red on the initial line:
if let ip = indexPath {
var data: NSManagedObject = tankningslista[ip.row] as NSManagedObject
cell.textLabel?.text = data.valueForKey("datum") as String
}
The whole function looks like this:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// Configure the cell...
let CellID: NSString = "Cell"
var cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier(CellID) as UITableViewCell
if let ip = indexPath {
var data: NSManagedObject = tankningslista[ip.row] as NSManagedObject
cell.textLabel?.text = data.valueForKey("datum") as String
}
return cell
}
I have followed this tutorial: https://www.youtube.com/watch?v=4ymz6i07DRM
try this way without using condition:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// Configure the cell...
let CellID: NSString = "Cell"
var cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier(CellID) as UITableViewCell
var data: NSManagedObject = tankningslista[indexPath.row] as NSManagedObject
cell.textLabel.text = data.valueForKey("datum") as? String
return cell
}
I have a UITableView with a lot of different cells, based on whats in the content array of the datasource they should show custom content.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell : UITableViewCell? = nil
let objectAtIndexPath: AnyObject = contentArray![indexPath.row]
if let questionText = objectAtIndexPath as? String {
cell = tableView.dequeueReusableCellWithIdentifier("questionCell", forIndexPath: indexPath) as QuestionTableViewCell
cell.customLabel.text = "test"
}
return cell!
}
Here I get the error that
UITableViewCell does not have the attribute customLabel
which QuestionTableViewCell does have. Whats wrong with my cast to QuestionTableViewCell?
The problem is not your cast but your declaration of cell. You declared it as an optional UITableViewCell and that declaration remains forever - and is all that the compiler knows.
Thus you must cast at the point of the call to customLabel. Instead of this:
cell.customLabel.text = "test"
You need this:
(cell as QuestionTableViewCell).customLabel.text = "test"
You could make this easier on yourself by declaring a different variable (since you know that in this particular case your cell will be a QuestionTableViewCell), but as long as you are going to have just one variable, cell, you will have to constantly cast it to whatever class you believe it really will be. Personally, I would have written something more like this, exactly to avoid that repeated casting:
if let questionText = objectAtIndexPath as? String {
let qtv = tableView.dequeueReusableCellWithIdentifier("questionCell", forIndexPath: indexPath) as QuestionTableViewCell
qtv.customLabel.text = "test"
cell = qtv
}
The problem is this var cell : UITableViewCell? = nil. You declare it as UITableViewCell? and it has that type forever.
You can declare another variable
let questionCell = cell as! QuestionTableViewCell
questionCell.customLabel.text = "test"
you can do any one of the following:
replace : cell.customLabel.text = "test"
with
cell?.customLabel.text = "text1"
change var cell : UITableView? = nil to var cell : UITableView!
I'm trying to make an app for iOS 8, using swift. The goal here is to make a kind of news feed. This feed displays posts from users, which follows a certain pattern.
I thought of using the UITableView where each cell follows a custom layout. The problem appears when I try to access a text label inside it. I try to access it by its tag, but when I do it, the whole app crashes. The error reported is "Swift dynamic cast failed", and I'm using the following code to access the view:
override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
let cellId: String = "cell"
var cell : UITableViewCell = tableView.dequeueReusableCellWithIdentifier(cellId) as UITableViewCell
if let ip = indexPath{
cell.textLabel.text = myData[ip.row] as String
var lbl = cell.contentView.viewWithTag(0) as UILabel
lbl.text = "ola"
}
return cell
}
Am I doing something wrong? Thanks in advance!
i think the Problem is the Tag 0. All Views are on default value 0. So try another tag value.
Just faced the same issue. The solution was to change tag to 10 and 20. I used 1 and 2 before. Is anybody aware of a range of tags that is used by the system?
So my 'cellForRowAtIndexPath' for a table with an image and a label per row looks like this now:
internal func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCellWithIdentifier("cellIdentifier") as? UITableViewCell {
(cell.contentView.viewWithTag(10) as UIImageView).image = IMAGES[indexPath.row]
(cell.contentView.viewWithTag(20) as UILabel).text = LABELS[indexPath.row]
return cell
} else {
NSLog("Prototype did not work")
return UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "errorIdentifier")
}
}
Change the 0 to 1 or another tag, it work for me.
0 is overlapping to another cell label's tag.
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.