Unabled to change UITableViewCell properties - uitableview

I'm trying to change the accessory view / accessory type of my table view cells, but it doesn't work.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell: UITableViewCell?
switch indexPath.row {
case 0:
cell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "enabledCell")
cell!.textLabel?.text = "Alarm enabled"
var enabledSwitch = UISwitch(frame: CGRectZero)
cell!.accessoryView = enabledSwitch
case 1:
cell = self.tableView.dequeueReusableCellWithIdentifier("calendarCell", forIndexPath: indexPath) as? UITableViewCell
cell!.textLabel?.text = "Calendar"
cell!.accessoryType = UITableViewCellAccessoryType.DisclosureIndicator
default:
cell = self.tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as? UITableViewCell
cell!.textLabel?.text = "Oops"
}
return cell!
}

I am not sure why this isnt working for you. I created a new project. Made a ViewController with a tableView in it and copied/pasted your code. Works. I get 1 cell with a switch, another with a disclosure, and one with no accessor. Is your table working at all? If your app just crashes maybe your reuseIdentifiers are misspelled or something. Maybe you didnt link your tableView to your ViewController as the delegate/datasource. Good Luck!
import Foundation
import UIKit
class MyTableViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
return 3
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
var cell: UITableViewCell?
switch indexPath.row {
case 0:
cell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "enabledCell")
cell!.textLabel?.text = "Alarm enabled"
var enabledSwitch = UISwitch(frame: CGRectZero)
cell!.accessoryView = enabledSwitch
case 1:
cell = self.tableView.dequeueReusableCellWithIdentifier("calendarCell", forIndexPath: indexPath) as? UITableViewCell
cell!.textLabel?.text = "Calendar"
cell!.accessoryType = UITableViewCellAccessoryType.DisclosureIndicator
default:
cell = self.tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as? UITableViewCell
cell!.textLabel?.text = "Oops"
}
return cell!
}
}

Related

Custom UITableViewCell created from .xib doesn't show

I'm lost. I searched and searched and cannot find the reason why my custom cell isn't displayed.
// ProfileCell.swift:
import UIKit
import QuartzCore
class ProfileCell: UITableViewCell {
#IBOutlet weak var profileNameLabel: UILabel!
#IBOutlet weak var profilePictureView: UIImageView!
}
The second default TableViewCell is displayed normally. I have no missing constraints in Interface Builder or any Errors. ProfileCell is selected in the ProfileCell.xib identity tab as the custom class.
// MoreTableViewControllerIB.swift
import UIKit
class MoreTableViewControllerIB: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 2
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// this cell is missing
if indexPath.row == 0 {
tableView.register(UINib(nibName: "ProfileCell", bundle: nil), forCellReuseIdentifier: "ProfileCell")
let cell = tableView.dequeueReusableCell(withIdentifier: "ProfileCell", for: indexPath) as! ProfileCell
cell.profileCommentLabel.text = "Test Comment Label"
cell.profilePictureView.image = UIImage(named:"profile_picture_test")
return cell
// this cell is displayed perfectly
}else if indexPath.row == 1 {
let cell = tableView.dequeueReusableCell(withIdentifier: "statisticsCell") ?? UITableViewCell(style: .default, reuseIdentifier: "statisticsCell")
cell.accessoryType = UITableViewCellAccessoryType.disclosureIndicator
cell.textLabel?.text = "Statistics"
cell.imageView.image = UIImage(named:"statistics")
return cell
// has to return a cell in every scenario
}else{
let cell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as UITableViewCell
return cell
}
}
}
Here is a screenshot of what I get.
tableView.register(UINib(nibName: "ProfileCell", bundle: nil), forCellReuseIdentifier: "ProfileCell")
add this line in viewDidLoad or viewWillApppear
So I found out what my mistake was. Pretty stupid and it cost me half a day:
The cell was already displayed, but the default height wasn't big enough to see it. I thought the set height in the .xib would be used. It apparently is not.
So I added this:
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if indexPath.row == 0 {
return 192 // the height for custom cell 0
}
}
In my case I had to additionally register nib with view of my cell:
myTableView.register(UINib(nibName: "nibwithcell", bundle: nil), forCellReuseIdentifier: "cell") // you need to register xib file

detailTextLabel isn't displayed but 100% set

I have an MGSwipeTableCell added in my tableView like this:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let reuseIdentifier = "Cell"
var cell = tableView.dequeueReusableCellWithIdentifier(reuseIdentifier) as! MGSwipeTableCell!
if cell == nil {
cell = MGSwipeTableCell(style: UITableViewCellStyle.Default, reuseIdentifier: reuseIdentifier)
}
cell.delegate = self
cell.backgroundColor = blue
}
All works fine. But now If I tap the cell the color of the cell changes for maybe a second to white and then to green (default color is blue). This is what should happen if the cell has been pressed:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let mySelectedCell = tableView.cellForRowAtIndexPath(indexPath) as! MGSwipeTableCell!
mySelectedCell.backgroundColor = green
mySelectedCell.detailTextLabel?.text = "Test"
}
So the color should only change to green not to white and then to green and a detailTextLabel with the text "Test" should be displayed.
I hope you can help me to solve this problem. I don't really know what to do.
Solution:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let reuseIdentifier = "Cell"
var cell = tableView.dequeueReusableCellWithIdentifier(reuseIdentifier) as! MGSwipeTableCell!
cell = MGSwipeTableCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: reuseIdentifier)
cell.selectionStyle = UITableViewCellSelectionStyle.None
cell.delegate = self
cell.backgroundColor = blue
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let reuseIdentifier = "Cell"
var cell = tableView.dequeueReusableCellWithIdentifier(reuseIdentifier) as! MGSwipeTableCell!
if cell == nil {
//Change this line
cell = MGSwipeTableCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: reuseIdentifier)
}
//And this line
cell.selectionStyle = UITableViewCellSelectionStyle.None
cell.delegate = self
cell.backgroundColor = blue
}
leave everything as is inside "didSelectRowAtIndexPath"

UITableViewCell not showing detailTextLabel.text - Swift

The detail (subtitle) text does not appear. The data are available, though, because when a println() call is added, it prints Optional("data") to the console with the expected data. In the storyboard, the UITableViewController is set to the proper class, the Table View Cell Style is set to 'Subtitle', and the reuse identifier is set to 'cell'. How can I get the subtitle information to display?
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as UITableViewCell
dispatch_async(dispatch_get_main_queue(), { () -> Void in
cell.textLabel.text = self.myArray[indexPath.row]["title"] as? String
cell.detailTextLabel?.text = self.myArray[indexPath.row]["subtitle"] as? String
println(self.myArray[indexPath.row]["subtitle"] as? String)
// The expected data appear in the console, but not in the iOS simulator's table view cell.
})
return cell
}
Your code looks fine. Just goto the storyboard and select the cell of your tableview -> Now goto Attributes Inspector and choose the style to Subtitle.
Follow this according to the below screenshot.
Hope it helped..
Same issue here (from what I've read, perhaps a bug in iOS 8?), this is how we worked around it:
Delete the prototype cell from your storyboard
Remove this line:
var cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as UITableViewCell
Replace with these lines of code:
let cellIdentifier = "Cell"
var cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier) as? UITableViewCell
if cell == nil {
cell = UITableViewCell(style: UITableViewCellStyle.Value2, reuseIdentifier: cellIdentifier)
}
Update for Swift 3.1
let cellIdentifier = "Cell"
var cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier)
if cell == nil {
cell = UITableViewCell(style: UITableViewCellStyle.value2, reuseIdentifier: cellIdentifier)
}
Update for Swift 4.2 - Simplified
let cell = UITableViewCell(style: UITableViewCell.CellStyle.value2, reuseIdentifier: "cellId")
Update for Swift 5 - Simplified
let cell = UITableViewCell(style: .value2, reuseIdentifier: "cellId")
If you still want to use prototype cell from your storyboard, select the TableViewcell style as Subtitle. it will work.
Try this it work for me (swift 5)
let cell = UITableViewCell(style: .value1, reuseIdentifier: "cellId")
cell.textLabel.text = "Déconnexion"
cell.imageView.image = UIImage(named: "imageName")
Objective c :
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:#"cellId"];
If you are setting the text to nil somewhere when you try to set it to a non-nil value the actual view that contains the text will be missing. This was introduced in iOS8. Try setting to an empty space #" " character instead.
See this: Subtitles of UITableViewCell won't update
If doing so programmatically without cells in interface builder this code works like a charm in Swift 2.0+
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
yourTableView.delegate = self
yourTableView.dataSource = self
yourTableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "subtitleCell")
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return yourTableViewArray.count
}
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
let cell: UITableViewCell = yourTableView.dequeueReusableCellWithIdentifier("subtitleCell", forIndexPath: indexPath) as UITableViewCell
cell.textLabel?.text = "the text you want on main title"
cell.detailTextLabel?.text = "the text you want on subtitle"
return cell
}
For what it's worth: I had the problem of detail not appearing. That was because I had registered the tableView cell, which I should not have done as the cell prototype was defined directly in storyboard.
In Xcode11 and Swift5 , We have to do like below.
If we do it by checking the condition cell == nil and then creating UITableViewCell with cellStyle it is not working . Below solution is working for me .
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellIdentifier = "Cell"
let cell = UITableViewCell(style: UITableViewCell.CellStyle.subtitle, reuseIdentifier: cellIdentifier)
cell?.textLabel?.text = "Title"
cell?.detailTextLabel?.text = "Sub-Title"
return cell!
}
Here is how it works for swift 5, to get a subtitle using detailtextlabel, using a UITableView object within a view controller, if you are missing any of these, it will not work and will probably crash.
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource
In viewDidLoad:
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "subtitleCell")
Delegate Function:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// Fetch a cell of the appropriate type.
let cell = UITableViewCell(style: .subtitle , reuseIdentifier: "subtitleCell")
// Configure the cell’s contents.
cell.textLabel!.text = "Main Cell Text"
cell.detailTextLabel?.text = "Detail Cell Text"
return cell
}
xcode 11
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath)
let cell = UITableViewCell(style: UITableViewCell.CellStyle.value1, reuseIdentifier: "reuseIdentifier")
cell.detailTextLabel?.text = "Detail text"
cell.textLabel?.text = "Label text"
// Configure the cell...
return cell
}
Some of the solutions above are not entirely correct. Since the cell should be reused, not re-created. You can change init method.
final class CustomViewCell: UITableViewCell {
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: .value1, reuseIdentifier: reuseIdentifier)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Three properties will be deprecated in a future release: imageView textLabel and detailTextLabel
You can use UIListContentConfiguration to configure cell
dataSource = UITableViewDiffableDataSource(tableView: tableview, cellProvider: { tableview, indexPath, menu in
let cell = tableview.dequeueReusableCell(withIdentifier: self.profileCellIdentifier, for: indexPath)
var content = cell.defaultContentConfiguration()
content.text = menu.title
if indexPath.section == MenuSection.info.rawValue {
content.image = UIImage(systemName: "person.circle.fill")
content.imageProperties.tintColor = AppColor.secondary
}
if let subtitle = menu.subTitle {
content.secondaryText = subtitle
}
cell.contentConfiguration = content
return cell
})
Swift 5 with subtitle text, here no need to register your cell in viewDidLoad:
var cell = tableView.dequeueReusableCell(withIdentifier: "cell")
if cell == nil {
cell = UITableViewCell(style: UITableViewCell.CellStyle.subtitle, reuseIdentifier: "cell")
}
cell?.textLabel?.text = "title"
cell?.textLabel?.numberOfLines = 0
cell?.detailTextLabel?.text = "Lorem ipsum"
cell?.detailTextLabel?.numberOfLines = 0
return cell ?? UITableViewCell()

UISwitch in UITableViewCell using Swift

I've been trying to get a UISwitch shown as an accessory view in my UITableViewCell, but it just won't show up. I think there might be something I'm overseeing.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = self.tableView.dequeueReusableCellWithIdentifier("enabledCell") as? UITableViewCell
if cell == nil {
cell = UITableViewCell(style: UITableViewCellStyle.Value1, reuseIdentifier: "enabledCell")
}
cell!.textLabel?.text = "Alarm enabled"
var enabledSwitch = UISwitch(frame: CGRectZero) as UISwitch
enabledSwitch.on = true
cell!.accessoryView = enabledSwitch
return cell!
}

UITableView in Swift

I'm struggling to figure out what's wrong with this code snippet. This is currently working in Objective-C, but in Swift this just crashes on the first line of the method. It shows an error message in console log: Bad_Instruction.
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
var cell : UITableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell") as UITableViewCell
if (cell == nil) {
cell = UITableViewCell(style: UITableViewCellStyle.Value1, reuseIdentifier: "Cell")
}
cell.textLabel.text = "TEXT"
cell.detailTextLabel.text = "DETAIL TEXT"
return cell
}
Also see matt's answer which contains the second half of the solution
Let's find a solution without creating custom subclasses or nibs
The real problem is in the fact that Swift distinguishes between objects that can be empty (nil) and objects that can't be empty. If you don't register a nib for your identifier, then dequeueReusableCellWithIdentifier can return nil.
That means we have to declare the variable as optional:
var cell : UITableViewCell?
and we have to cast using as? not as
//variable type is inferred
var cell = tableView.dequeueReusableCellWithIdentifier("CELL") as? UITableViewCell
if cell == nil {
cell = UITableViewCell(style: UITableViewCellStyle.Value1, reuseIdentifier: "CELL")
}
// we know that cell is not empty now so we use ! to force unwrapping but you could also define cell as
// let cell = (tableView.dequeue... as? UITableViewCell) ?? UITableViewCell(style: ...)
cell!.textLabel.text = "Baking Soda"
cell!.detailTextLabel.text = "1/2 cup"
cell!.textLabel.text = "Hello World"
return cell
Sulthan's answer is clever, but the real solution is: don't call dequeueReusableCellWithIdentifier. That was your mistake at the outset.
This method is completely outmoded, and I'm surprised it has not been formally deprecated; no system that can accommodate Swift (iOS 7 or iOS 8) needs it for any purpose whatever.
Instead, call the modern method, dequeueReusableCellWithIdentifier:forIndexPath:. This has the advantage that no optionals are involved; you are guaranteed that a cell will be returned. All the question marks and exclamation marks fall away, you can use let instead of var because the cell's existence is guaranteed, and you're living in a convenient, modern world.
You must, if you're not using a storyboard, register the table for this identifier beforehand, registering either a class or a nib. The conventional place to do that is viewDidLoad, which is as early as the table view exists at all.
Here's an example using a custom cell class:
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.registerClass(MyCell.self, forCellReuseIdentifier: "Cell")
}
// ...
override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath:indexPath) as MyCell
// no "if" - the cell is guaranteed to exist
// ... do stuff to the cell here ...
cell.textLabel.text = // ... whatever
// ...
return cell
}
But if you're using a storyboard (which most people do), you don't even need to register the table view in viewDidLoad! Just enter the cell identifier in the storyboard and you're good to go with dequeueReusableCellWithIdentifier:forIndexPath:.
#Sulthan's answer is spot on. One possible convenience modification would be to cast the cell as a UITableViewCell!, rather than a UITableViewCell.
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
var cell = tableView.dequeueReusableCellWithIdentifier("CELL") as UITableViewCell!
if !cell {
cell = UITableViewCell(style:.Default, reuseIdentifier: "CELL")
}
// setup cell without force unwrapping it
cell.textLabel.text = "Swift"
return cell
}
Now, you can modify the cell variable without force unwrapping it each time. Use caution when using implicitly unwrapped optionals. You must be certain that the value you are accessing has a value.
For more information, refer to the "Implicitly Unwrapped Optionals" section of The Swift Programming Language.
Try this:
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
cell.textLabel.text = "\(indexPath.row)"
return cell
}
Note that you should register you UITableViewCell and ID when creating instantiating your UITableView:
tableView.delegate = self
tableView.dataSource = self
tableView.registerClass(UITableViewCell.classForCoder(), forCellReuseIdentifier: "Cell")
Here is what I wrote to get it working...
First Register the table view cell with the table view
self.tableView.registerClass(MyTableViewCell.self, forCellReuseIdentifier: "Cell")
Then configure cellForRowAtIndexPath
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
var cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as MyTableViewCell
cell.textLabel.text = "Cell Text"
cell.detailTextLabel.text = "Cell Detail Text in Value 1 Style"
return cell
}
I then defined a custom cell subclass write at the bottom of the file (since its so much easier now)
class MyTableViewCell : UITableViewCell {
init(style: UITableViewCellStyle, reuseIdentifier: String!) {
super.init(style: UITableViewCellStyle.Value1, reuseIdentifier: reuseIdentifier)
}
}
Here is a simple way to define table cell in swift 2:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let identifier = "cell"
let cell = tableView.dequeueReusableCellWithIdentifier(identifier) ??
UITableViewCell.init(style: UITableViewCellStyle.Default, reuseIdentifier: identifier)
cell.textLabel!.text = "my text"
return cell
}
Swift 3:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let identifier = "cell"
let cell = tableView.dequeueReusableCell(withIdentifier: identifier) ??
UITableViewCell(style: .default, reuseIdentifier: identifier)
cell.textLabel!.text = "my text"
return cell
}
There's a few answers here, but I don't think any of them are ideal, because after the declaration you're ending up with an optional UITableViewCell, which then needs a cell!... in any declarations. I think this is a better approach (I can confirm this compiles on Xcode 6.1):
var cell:UITableViewCell
if let c = tableView.dequeueReusableCellWithIdentifier("cell") as? UITableViewCell {
cell = c
}
else {
cell = UITableViewCell()
}
Well, I have done this way:
Steps for UITableView using Swift:
Take UITableView in ViewController
Give Referencing Outlets in ViewController.swift class
Give Outlets dataSource & delegate to ViewController
Now Swift code in ViewController.swift class:
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var mTableView: UITableView!
var items: [String] = ["Item 1","Item 2","Item 3", "Item 4", "Item 5"]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.mTableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.items.count;
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell:UITableViewCell = self.mTableView.dequeueReusableCellWithIdentifier("cell") as! UITableViewCell
cell.textLabel?.text = self.items[indexPath.row]
println(self.items[indexPath.row])
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
println("You have selected cell #\(indexPath.row)!")
}
}
Now it's time to Run your program.
Done
Actually in the Apple's TableView Guide document and Sample Code you will find the sentence below:
If the dequeueReusableCellWithIdentifier: method asks for a cell that’s defined in a storyboard, the method always returns a valid cell. If there is not a recycled cell waiting to be reused, the method creates a new one using the information in the storyboard itself. This eliminates the need to check the return value for nil and create a cell manually.
So,we could just code like this:
var identifer: String = "myCell"
var cell = tableView.dequeueReusableCellWithIdentifier(identifer) as UITableViewCell
cell.textLabel.text = a[indexPath.row].name
cell.detailTextLabel.text = "detail"
I think this is a suitable way to use tableView
Using "as" keyword would do the following two steps:
1.creating a optional value which wrap a variable of UITableViewCell;
2.unwrapping the optional value.
So,by doing this
var cell : UITableViewCell = tableView.dequeueReusableCellWithIdentifier("Component") as UITableViewCell
you would get a "plain" UITableViewCell type variable: cell.Theoretically speaking, it's ok to do this.But the next line
if (cell == nil) {}
makes trouble, because in swift, only the optional value can be assigned with nil.
So, to solve this problem, you have to make cell a variable of Optional type. just like this:
var cell = tableView.dequeueReusableCellWithIdentifier("Component") as? UITableViewCell
using the keyword "as?" would create a Optional variable, and this, undoubtedly, can be assigned with nil.
For cell template:
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
let myCell : youCell = youCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "cell")
return myCell
}
bro, please take a look at the sample https://github.com/brotchie/SwiftTableView
Why not this?
(please delete if i am not in the goal...)
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
if let cell: UITableViewCell = theTableView.dequeueReusableCellWithIdentifier("myCell", forIndexPath: indexPath) as? UITableViewCell {
// cell ok
}else{
// not ok
}
}
I have done in following way: to show detailTextLabel. text value
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let CellIdentifier: String = "cell"
var cell = tableView.dequeueReusableCellWithIdentifier(CellIdentifier) as? UITableViewCell
if cell == nil {
cell = UITableViewCell(style: UITableViewCellStyle.Value1, reuseIdentifier: CellIdentifier)
}
//cell.accessoryType = UITableViewCellAccessoryType.DisclosureIndicator
// parse the value of records
let dataRecord = self.paymentData[indexPath.row] as! NSDictionary
let receiverName = dataRecord["receiver_name"] as! String
let profession = dataRecord["profession"] as! String
let dateCreated = dataRecord["date_created"] as! String
let payAmount = dataRecord["pay_amount"] as! String
println("payment \(payAmount)")
cell!.textLabel?.text = "\(receiverName)\n\(profession)\n\(dateCreated)"
cell!.detailTextLabel?.text = "$\(payAmount)"
cell!.textLabel?.numberOfLines = 4
return cell!
}// end tableview
UITableView Demo using Playground
//: Playground - noun: a place where people can play
import UIKit
import PlaygroundSupport
class TableviewDemoDelegate:NSObject,UITableViewDataSource,UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 100
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell:UITableViewCell? = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath as IndexPath)
if cell == nil {
cell = UITableViewCell(style: .default, reuseIdentifier: "cell")
}
cell?.textLabel?.text = "Item \(indexPath.row+1)"
return cell!
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("You have selected cell #\(indexPath.row)!")
}
}
var tableView = UITableView(frame:CGRect(x: 0, y: 0, width: 320, height: 568), style: .plain)
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
let delegate = TableviewDemoDelegate()
tableView.delegate = delegate
tableView.dataSource = delegate
PlaygroundPage.current.liveView = tableView
I went through your codes and most probably the reason for the crash is you are trying to typecast an optional value which is not assigned
Now consider the line of code below
var cell : UITableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell") as UITableViewCell
When there are no cells in the tableview you are still trying to typecast as UITableView.When the compiler tries to typecast nil value you face this issue
The correct statement should be
var cell : UITableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell")
You can use if else statement to typecast for values which holds
Try this code
var cell:CustomTableViewCell = tableView.dequeueReusableCellWithIdentifier("CustomTableViewCell") as CustomTableViewCell
cell.cellTitle.text="vijay"
https://github.com/iappvk/TableView-Swift

Resources