3

I'm currently working on an exercise swift program, one that requires CoreData results to be displayed on a table.

I've structured my app such that the storyboard itself doesn't contain any UI elements, only views (with an accompanying UIViewController class), which then loads custom nibs / xibs (also accompanied by a UIView Subclass). In this case, the xib contains a UITableView, and a separate xib contains the cell.

TableView Class:

import UIKit

protocol SkillsViewDelegate{
}

class SkillsView: UIView {
    var delegate : SkillsViewDelegate!
    @IBOutlet weak var skillsTable: UITableView!
}

TableView Controller:

import UIKit
import CoreData

class SkillsViewController: UIViewController, SkillsViewDelegate, UITableViewDataSource, UITableViewDelegate {
    var displaySkillsView : SkillsView!
    var displaySkillsCell : SkillViewCell!
    let textCellIdentifier = "skillViewCell"

    override func viewDidLoad() {
        super.viewDidLoad()

        self.displaySkillsView = UIView.loadFromNibNamed("SkillsView") as! SkillsView
        self.displaySkillsView.delegate = self
        self.view = self.displaySkillsView
        // Do any additional setup after loading the view.
    }

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

    //MARK : -Table view delegates

    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        // #warning Incomplete implementation, return the number of sections
        return 1
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete implementation, return the number of rows
        return 1
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier(textCellIdentifier, forIndexPath: indexPath)

        return cell
    }
}

TableCellView Class:

import UIKit

protocol SkillsViewCellDelegate{
}

class SkillViewCell: UITableViewCell {
    var delegate : SkillsViewCellDelegate!

    override func awakeFromNib() {
        super.awakeFromNib()
    }

    override func setSelected(selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
   }

    @IBOutlet weak var skillName: UILabel!
    @IBOutlet weak var skillRank: UILabel!
}

I can't figure out how to call the cell xib into the controller. I would guess it's something like this problem, but the difference is the guy is using a UITableViewController. I tried adding that as well, but I get a Multiple inheritance from classes 'UIViewController' and 'UITableViewController' for my troubles.

What I Tried:
I tried adding UITableViewController up top, but I get a Multiple inheritance from classes 'UIViewController' and 'UITableViewController' for my troubles.

Any suggestions?

Community
  • 1
  • 1
zack_falcon
  • 4,186
  • 20
  • 62
  • 108

2 Answers2

7

You can just register your SkillsViewCell in your SkillsViewController

Obj C

-(void)viewDidLoad {
   [super viewDidLoad];
   UINib *cellNib = [UINib nibWithNibName:@"NibName" bundle:nil];
   [self.skillsTable registerNib:cellNib forCellReuseIdentifier:textCellIdentifier];
}

Swift 2

override func viewDidLoad() {
   super.viewDidLoad()
   let nibName = UINib(nibName: "NibName", bundle:nil)
   self.skillsTable.registerNib(nibName, forCellReuseIdentifier: textCellIdentifier)
}

Swift 4

override func viewDidLoad() {
   super.viewDidLoad()
   let nibName = UINib(nibName: "NibName", bundle:nil)
   self.skillsTable.register(nibName, forCellReuseIdentifier: textCellIdentifier)
}

Then only inherit from UIViewController not UITableViewController

To call methods specific to your custom cell

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier(textCellIdentifier, forIndexPath: indexPath) as! SkillViewCell

    cell.skillName.text = "Some text"
    cell.skillRank.text = "Some text"
    return cell
}
Paul Solt
  • 8,375
  • 5
  • 41
  • 46
Scott Lewis
  • 437
  • 4
  • 18
  • Thanks for the quick reply. I actually tried the latter already (apologies for not mentioning it), but I get an error saying `Ambiguous reference to member 'tableView'`. – zack_falcon Dec 12 '15 at 06:51
  • You can change self.tableView to self.skillsTable – Scott Lewis Dec 12 '15 at 06:54
  • Ah, gotcha. How do I call the `skillName` and `skillRank` from `cellForRowAtIndexPath`? So far, I've got this in there: `let cell = self.displaySkillsView.skillsTable.dequeueReusableCellWithIdentifier(textCellIdentifier, forIndexPath: indexPath)` – zack_falcon Dec 12 '15 at 07:02
  • Thanks. The cells still aren't appearing, though. The table is definitely there, coloured grey. Perhaps something with the delegates? – zack_falcon Dec 12 '15 at 07:32
  • Ah, got it. I did forget to set the delegates and datasource. – zack_falcon Dec 12 '15 at 10:09
  • Where to call registerNib when the table is inside a Custom UIView? awakeFromNib is called after tableview delegates which results in an error – nr5 Jan 05 '20 at 10:05
0

I think you will need to use

func registerNib(_ nib: UINib?, forCellReuseIdentifier identifier: String)

in viewDidLoad

https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITableView_Class/#//apple_ref/occ/instm/UITableView/registerNib:forCellReuseIdentifier:

mohamede1945
  • 7,092
  • 6
  • 47
  • 61