Search code examples
iosswiftuitableviewcell

Create Custom Dynamic Prototype Cells programmatically


I am having an issue trying to create Dynamic Prototype Cells programmatically. This is my first time trying this approach. I have always created them through storyboard.

I have my ViewController.swift file which contains the following

var noteListTableView: UITableView = UITableView()

noteListTableView.frame.origin.x = 0.0
noteListTableView.frame.origin.y = kNAV_BAR_HEIGHT
noteListTableView.frame.size.width = kDEVICE_WIDTH
noteListTableView.frame.size.height = kDEVICE_HEIGHT - kNAV_BAR_HEIGHT
noteListTableView.dataSource = self
noteListTableView.delegate = self
self.view.addSubview(noteListTableView)

Also in the file, I have included the appropriate TableView delegate and Data source functions

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    return GlobalDataController.notesDB.count
}

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

    var aNote: NoteItem = GlobalDataController.notesDB[indexPath.row] as NoteItem

    if var cell: NoteListTVCell = noteListTableView.dequeueReusableCellWithIdentifier(kReuseCellNoteList) as? NoteListTVCell {

        cell.noteTitle.text = "Title"
        cell.noteContentSummary.text = "Content Summary"
        cell.noteDate.text = "May 20"

            return cell
        }
    else{

        var cell: NoteListTVCell = NoteListTVCell(style: UITableViewCellStyle.Default, reuseIdentifier: kReuseCellNoteList)

        cell.noteTitle.text = "Title"
        cell.noteContentSummary.text = "Content Summary"
        cell.noteDate.text = "May 20"

        return cell
    }
}

(1) The IF-STATEMENT always seems to fail, that is why I added the else statement as per some example I found online for Obj-C.

(2) When the ELSE is triggered, the program always crashes trying to assign the cell.* values, saying it encountered a nil value.

EDIT: NoteListTVCell

class NoteListTVCell: UITableViewCell {

    var noteTitle: UILabel!
    var noteContentSummary: UILabel!
    var noteDate: UILabel!

    var cellMargin: CGFloat = kPadding * 3

    override func awakeFromNib() {
        super.awakeFromNib()

        noteTitle = UILabel(frame: CGRect(x: cellMargin, y: kPadding, width: kDEVICE_WIDTH - cellMargin - kPadding, height: 30.0))
        noteTitle.backgroundColor = kColorTransparent
        noteTitle.font = UIFont(name: kFont02, size: 20.0)
        noteTitle.textColor = Scripts.hexColor(0x000000, alpha: 0.8)
        noteTitle.text = "Title"
        self.addSubview(noteTitle)

        /* Note Content Summary
        -----------------------------------------------------------------------------------------*/
        var noteContentSummaryY: CGFloat = noteTitle.frame.origin.y + noteTitle.frame.size.height

        noteContentSummary = UILabel(frame: CGRect(x: cellMargin, y: noteContentSummaryY, width: kDEVICE_WIDTH - cellMargin - kPadding, height: 20.0))
        noteContentSummary.backgroundColor = kColorTransparent
        noteContentSummary.font = UIFont(name: kFont02, size: 14.0)
        noteContentSummary.textColor = Scripts.hexColor(0x000000, alpha: 0.4)
        noteContentSummary.text = "This is a summary..."
        self.addSubview(noteContentSummary)

        /* Note Date
        -----------------------------------------------------------------------------------------*/
        noteDate = UILabel(frame: CGRect(x: kDEVICE_WIDTH - 100.0 - kPaddingx2, y: kPadding, width: 100.0, height: 20.0))
        noteDate.backgroundColor = kColorTransparent
        noteDate.font = UIFont(name: kFont02, size: 10.0)
        noteDate.textColor = Scripts.hexColor(kColorThemeBlue, alpha: 1.0)
        noteDate.textAlignment = NSTextAlignment.Right
        noteDate.text = "May 8, 2:14 AM"
        self.addSubview(noteDate)
    }
}

Solution

  • You haven't override the init method in your custom cell, but anyway it will call super init method, if you don't provide. Put your cell initialisation code in init method instead of awakeFromNib method.

    Try this below.

        required init(coder aDecoder: NSCoder) {
    
                super.init(coder: aDecoder)
        }
    
    
        override init(style: UITableViewCellStyle, reuseIdentifier: String!) {
    
             super.init(style: style, reuseIdentifier: reuseIdentifier)
             //Do your cell set up
            noteTitle = UILabel(frame: CGRect(x: cellMargin, y: kPadding, width: kDEVICE_WIDTH - cellMargin - kPadding, height: 30.0))
            noteTitle.backgroundColor = kColorTransparent
            noteTitle.font = UIFont(name: kFont02, size: 20.0)
            noteTitle.textColor = Scripts.hexColor(0x000000, alpha: 0.8)
            noteTitle.text = "Title"
            self.addSubview(noteTitle)
    
            /* Note Content Summary
            -----------------------------------------------------------------------------------------*/
            var noteContentSummaryY: CGFloat = noteTitle.frame.origin.y + noteTitle.frame.size.height
    
            noteContentSummary = UILabel(frame: CGRect(x: cellMargin, y: noteContentSummaryY, width: kDEVICE_WIDTH - cellMargin - kPadding, height: 20.0))
            noteContentSummary.backgroundColor = kColorTransparent
            noteContentSummary.font = UIFont(name: kFont02, size: 14.0)
            noteContentSummary.textColor = Scripts.hexColor(0x000000, alpha: 0.4)
            noteContentSummary.text = "This is a summary..."
            self.addSubview(noteContentSummary)
    
            /* Note Date
            -----------------------------------------------------------------------------------------*/
            noteDate = UILabel(frame: CGRect(x: kDEVICE_WIDTH - 100.0 - kPaddingx2, y: kPadding, width: 100.0, height: 20.0))
            noteDate.backgroundColor = kColorTransparent
            noteDate.font = UIFont(name: kFont02, size: 10.0)
            noteDate.textColor = Scripts.hexColor(kColorThemeBlue, alpha: 1.0)
            noteDate.textAlignment = NSTextAlignment.Right
            noteDate.text = "May 8, 2:14 AM"
            self.addSubview(noteDate)
        }
    

    Do this in viewDidLoad

    override func viewDidLoad() {
            super.viewDidLoad()
            noteListTableView = UITableView(frame: self.view.frame, style: UITableViewStyle.Plain)
            noteListTableView.dataSource = self
            noteListTableView.delegate = self
            self.view.addSubview(noteListTableView)
            noteListTableView.registerClass(NoteListTVCellTableViewCell.self, forCellReuseIdentifier: kReuseCellNoteList)
            // Do any additional setup after loading the view, typically from a nib.
        }