JonP
JonP

Reputation: 67

UITableView, does not conform to protocol - how to declare several?

I understand that I need to implement required methods in the controller and establish a relationship between view and controller.. but where do the identifier "tableView" in

 func tableView(mintabell: UITableView, numberOfRowsInSection section: Int) -> Int
{
    return  items.count
}

come from and what if I want several tableviews on same view? How to declare them separately?

Upvotes: 0

Views: 427

Answers (4)

Natasha
Natasha

Reputation: 6893

First of all, you don't necessarily always have to implement a protocol for every view. Only when you have a view which has delegate that needs implementing, you will have to conform that protocol responsible for that delegate implementation.

So for tableView, first you drag a UITableView in your Controller from the Object Library and then a UITableViewCell under the Table View.

enter image description here

Now go to the ViewController.swift file and add

@IBOutlet var myFirstTableView: UITableView!

right after the line.

class ViewController: UIViewController 

P.S: If you have more than one table then you could just declare the extra table's here., like-

@IBOutlet var mySecondTableView: UITableView!

Now, let's assume, you have one table. Now, you need to add the list of protocols. So, just add UITableViewDelegate, UITableViewDataSource with

class ViewController: UIViewController

appended by comma.

Adding this should give you an error but that's okay. This is because you have not added the required method listed under that UITableViewDatasource protocol.

So, just add those required methods and implement it accordingly.

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 3;
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        var cell:UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("myCell") as! UITableViewCell

        cell.textLabel?.text = "test"

        return cell
    }

Here, I said, I will have 3 cells whose identifier is "myCell" and the cell's textLabel will have a text, "test".

Now, we forgot a very important step and that is to assign the cell identifier to our TableView Cell. So, go to the storyboard and select the TableView Cell and insert "myCell" as an identifier for your cell.

enter image description here

If you had more than one table, then you would check for which TableView, you are loading your data. So, you could assign a unique tag to each table explicitly(you can do that either from storyboard or from code), and based on that tag, you would implement your methods. Let's say you have 3 tables and the assigned tag is 1,2 and 3. So, you could do something like,

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if tableView.tag == 1{
            return 3
        }
        else if tableView.tag == 2{
            return 4
        }
        else{
            return 1
        }

    }


    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        var cell:UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("cell") as! UITableViewCell
       if tableView.tag == 1{
         cell.textLabel?.text = "test1"
        }
       else  if tableView.tag == 2{
            cell.textLabel?.text = "test2"
        }
       else{
        cell.textLabel?.text = "test"
        }
        return cell
    }

Upvotes: 0

dibi
dibi

Reputation: 3275

Think of it like a box. Every tableView that is subscribed to the protocol grabs in that box leaves its fingerprint and takes what it gets. So if you have multiple tableViews in one controller you can distinguish them by checking for equality.

Example:

class MyViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    let firstTableView = UITableView()
    let secondTableView = UITableView()

    viewDidLoad() {
        firstTableView.delegate = self
        secondTableView.delegate = self
        firstTableView.dataSource = self
        secondTableView.dataSource = self
    }

   // ... some othe methods...

    func tableView(mintabell: UITableView, numberOfRowsInSection section: Int) -> Int
    {
       if tableView == firstTableView {
           return 10
       }

       if tableView == secondTableView {
           return 20
       }

       return 0
    }
}

Upvotes: 1

Swinny89
Swinny89

Reputation: 7373

These are the protocols that you need to declare for a TableView

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

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 
}


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

In terms of having more than one tableview in one ViewController.. If you have an outlet for each tableview then you can check which one you need inside the protocol functions:

@IBOutlet weak var tableViewOne: UITableView!
@IBOutlet weak var tableViewTwo: UITableView!

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    if tableView == self.tableViewOne {
        return createCellForTableViewOneAndReturnItHere
    } else {
        return createCellForTableViewOneAndReturnItHere
    }
}

Upvotes: 2

zaph
zaph

Reputation: 112855

Delegates are implemented by the developer and called by iOS not the developer. The tableView is passed by iOS and points to the particular tableview.

If you have several tableviews with the same delegate you can compare the passed tableview parameter to the tableviews you have implemented to determine which one.

Alternatively, create a tableView delegate and datasource per tableView. This will eliminate testing which tableView removing a lot of conditional logic from the code.

Upvotes: 0

Related Questions