josephine josephine - 3 years ago 174
iOS Question

Two tableViews in same ViewController won't show in swift 3

I am trying to have two UITableViews in the same ViewController. I am trying to do all of it programmatically but for some reason neither of the tableViews display at all.

I have noticed that the code never gets to

else if tableView == self.tableView2 {

}


in the cellForRowAt method. I have no idea why this is the case.

I appreciate any help to solve this.

import UIKit

class TestViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

var tableView1: UITableView?
var tableView2: UITableView?

let tableView1Data = ["Option 1", "Option 2", "Option 3", "Option 4", "Other"]
let tableView2Data = ["Cancel"]

override func viewDidLoad() {
super.viewDidLoad()

view.backgroundColor = .apricot

// Initalize
tableView1 = UITableView()
tableView2 = UITableView()

// Register cells
// tableView1!.register(UITableViewCell.self, forCellReuseIdentifier: "Cell1")
// tableView2!.register(UITableViewCell.self, forCellReuseIdentifier: "Cell2")

tableView1!.register(UINib(nibName: "yourNib", bundle: nil), forCellReuseIdentifier: "Cell1")
tableView2!.register(UINib(nibName: "yourNib", bundle: nil), forCellReuseIdentifier: "Cell2")

// Set delegates
tableView1!.delegate = self
tableView1!.dataSource = self

tableView2!.delegate = self
tableView2!.dataSource = self

// Add to view
view.addSubview(tableView1!)
view.addSubview(tableView2!)

// Set size constraints
tableView1!.translatesAutoresizingMaskIntoConstraints = false
tableView1!.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
tableView1!.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
tableView1!.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true

tableView2!.translatesAutoresizingMaskIntoConstraints = false
tableView2!.topAnchor.constraint(equalTo: tableView1!.bottomAnchor, constant: 15).isActive = true
tableView2!.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
tableView2!.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true

// Customize looks
tableView1!.layer.cornerRadius = 10
tableView2!.layer.cornerRadius = 10

// Reload data
tableView1!.reloadData()
tableView2!.reloadData()
}

override func viewDidAppear(_ animated: Bool) {
tableView1!.reloadData()
tableView2!.reloadData()
}

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

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

if tableView == self.tableView1 {
return tableView1Data.count
}

else if tableView == self.tableView2 {
return tableView2Data.count
}
return 0
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

var cell: UITableViewCell?

if tableView == self.tableView1 {

cell = tableView.dequeueReusableCell(withIdentifier: "Cell1", for: indexPath)
guard let cell = cell else {return UITableViewCell()}

let cellLabel = UILabel()
cellLabel.text = tableView1Data[indexPath.row]
cellLabel.textColor = .black
cell.addSubview(cellLabel)
cellLabel.frame = cell.frame
}

else if tableView == self.tableView2 {

cell = tableView.dequeueReusableCell(withIdentifier: "Cell2", for: indexPath)
guard let cell = cell else {return UITableViewCell()}

let cellLabel = UILabel()
cellLabel.text = tableView2Data[indexPath.row]
cellLabel.textColor = .black
cell.addSubview(cellLabel)
cellLabel.frame = cell.frame

}
return cell!
}

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return view.frame.height * 0.1
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
//...
}

}

Answer Source

You need to somehow constrain the height of either tableView1 or tableView2 (Once you have established 1 height, the other can be inferred). At the moment you have told autolayout that the two table views must be 15 apart vertically, but not where that separation is in terms of the superview. As a result, autolayout is probably sizing tableView1 to the full height of the superview and the other tableview isn’t on screen, so it’s datasource methods don’t get called

For example, to set the table views to half the screen each:

  TableView1!.bottomAnchor.constraint(equalTo:self.view.centerYAnchor, constant:-7).isActive=true
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download