Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

cellForRowAtIndexPath is not being called from custom class

I'm using Xcode 7.0, Swift 2

I'm basically trying to create a custom class that will build a UITable, then in the ViewController I make a new object of the table and load it into self.view;

The problem I'm having is that the function func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell isn't being called at all from within the custom class. I've been looking for a solution for 3 days now and I've tried rebuilding the App and code several times with no luck.

Please note, if I use the same code (that is everything required to build the table; excluding init functions, etc) in the ViewController.swift file, it works fine.

I know the problem is with the cellForRowAtIndexPath function because it will not print out the statement I set in that block of code when it runs. All other functions are called, but for some reason this isn't being called. Not sure if I overlooked something here. Any help would be appreciated. Thanks in advance.

class sideTest: NSObject, UITableViewDelegate, UITableViewDataSource {


    let tesTable: UITableView = UITableView()
    var items: [String]?
    var mView: UIView = UIView()

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        print("The number of rows is: \(self.items!.count)")

        return self.items!.count
    }

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

        print("\nLets create some cells.")

        let sCell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier("cell") as UITableViewCell!

        sCell.textLabel?.text = self.items![indexPath.row]
        sCell.textLabel?.textColor = UIColor.darkTextColor()

        return sCell
    }

    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        print("You selected cell #\(indexPath.row)!")
    }

    func tblSetup() {

        self.tesTable.frame = CGRectMake(0, 0, 320, mView.bounds.height)
        self.tesTable.delegate = self
        self.tesTable.dataSource = self

        self.tesTable.backgroundColor = UIColor.cyanColor()

        // load cells
        self.tesTable.registerClass(UITableViewCell.self, forCellReuseIdentifier: "Cell")
        self.tesTable.reloadData()

        print("Currenlty in tblSetup.\nCurrent rows is: \(self.items!.count)")
    }

    //Init

    override init() {
        super.init()

        self.items = nil

        self.tblSetup()
    }

    init(sourceView: UIView , itemListAsArrayString: [String]) {
        super.init()

        self.items = itemListAsArrayString
        self.mView = sourceView

        self.tblSetup()
    }
}

Here is the code from ViewController.swift; Please do note that the table gets built, but the cells do not populate, even if I manually enter cell info by doing: sCell.textLabel?.text = "test cell"

class ViewController: UIViewController {



    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        let myTable: sideTest = sideTest(sourceView: self.view, itemListAsArrayString: ["Cell 1", "Cell 2", "Cell 3"])
        self.view.addSubview(myTable.tesTable)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }   
}

Again, any help is greatly appreciated. Thanks.

enter image description here

like image 351
Marlon Mingo Avatar asked Sep 19 '15 18:09

Marlon Mingo


2 Answers

Your view controller don't have a strong reference to your sideTest var. Once your view did load finished,your sideTest is nil.Although you have a tableview(by add subview), but you no longer have a data source.

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

is called after view did load. That cause the problem.

change your view controller to:

    var tb :sideTest?


override func viewDidLoad() {
    super.viewDidLoad()
    let myTable: sideTest = sideTest(sourceView: self.view, itemListAsArrayString: ["Cell 1", "Cell 2", "Cell 3"])
    print(myTable.tesTable.frame)
    tb=myTable
    self.view.addSubview(myTable.tesTable)
}

change your cellforrowatindexpath to:

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

    print("create cells")
    var cell :UITableViewCell?

    if let sCell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier("cell"){
       cell=sCell

    }else{
        cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "cell")

    }


    cell!.textLabel?.text = self.items![indexPath.row]
    cell!.textLabel?.textColor = UIColor.darkTextColor()

    return cell!
}

this will fix most of the problems.

like image 99
wj2061 Avatar answered Nov 14 '22 22:11

wj2061


Your code:

override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        let myTable: sideTest = sideTest(sourceView: self.view, itemListAsArrayString: ["Cell 1", "Cell 2", "Cell 3"])
        self.view.addSubview(myTable.tesTable)
    }

I would think that the myTable variable goes out of scope and is released when viewDidLoad finishes, so there is no data source or delegate after that. Did you verify that the self.view.addSubview(myTable.tesTable) retains it? Try moving declaration of myTable outside of the function level (to property level) or add a diagnostic print to deinit..

like image 37
MirekE Avatar answered Nov 15 '22 00:11

MirekE