sheishistoric
sheishistoric

Reputation: 85

TableView not appearing in simulator?

I have created an iOS application with Single View Application template. Once I run the application the launch screen appears for about 2 second and then displays the blue navbar, but a blank white background.

blue navbar, but a blank white background.

I think the issue must be with the subview of the tableView, but it's not clear to me how to fix that. (I'm not using storyboard, but will implement a start screen at some point. Would that solve my problem?)

import UIKit

struct Question {
    var questionString: String?
    var answers: [String]?
    var selectedAnswerIndex: Int?
}

class QuestionController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    let cellId = "cellId"
    let headerId = "headerId"
    var tableView: UITableView?

    static var questionsList: [Question] = [Question(questionString: "What is your favorite type of food?", answers: ["Sandwiches", "Pizza", "Seafood", "Unagi"], selectedAnswerIndex: nil), Question(questionString: "What do you do for a living?", answers: ["Paleontologist", "Actor", "Chef", "Waitress"], selectedAnswerIndex: nil), Question(questionString: "Were you on a break?", answers: ["Yes", "No"], selectedAnswerIndex: nil)]

    override func viewDidLoad() {
        super.viewDidLoad()

        navigationItem.title = "Question"

        navigationController?.navigationBar.tintColor = UIColor.white
        navigationItem.backBarButtonItem = UIBarButtonItem(title: "Back", style: .plain, target: nil, action: nil)

        tableView = UITableView()
        tableView?.dataSource = self
        tableView?.delegate = self
        self.view.addSubview(self.tableView!)
        tableView?.register(AnswerCell.self, forCellReuseIdentifier: cellId)
        tableView?.register(QuestionHeader.self, forHeaderFooterViewReuseIdentifier: headerId)

        tableView?.sectionHeaderHeight = 50
        tableView?.tableFooterView = UIView()
    }

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

        if let index = navigationController?.viewControllers.index(of: self) {
            let question = QuestionController.questionsList[index]
            if let count = question.answers?.count {
                return count
            }
        }

        return 1
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath as IndexPath) as! AnswerCell
        if let index = navigationController?.viewControllers.index(of: self) {
            let question = QuestionController.questionsList[index]
            cell.nameLabel.text = question.answers?[indexPath.row]
        }

        return cell
    }

    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: headerId) as! QuestionHeader

        if let index = navigationController?.viewControllers.index(of: self) {
            let question = QuestionController.questionsList[index]
            header.nameLabel.text = question.questionString
        }

        return header
    }

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

        if let index = navigationController?.viewControllers.index(of: self) {
            QuestionController.questionsList[index].selectedAnswerIndex = indexPath.item

            if index < QuestionController.questionsList.count - 1 {
                let questionController = QuestionController()
                navigationController?.pushViewController(questionController, animated: true)
            } else {
                let controller = ResultsController()
                navigationController?.pushViewController(controller, animated: true)
            }
        }
    }

}

class ResultsController: UIViewController {

    let resultsLabel: UILabel = {
        let label = UILabel()
        label.text = "Congratulations, you'd make a great Ross!"
        label.translatesAutoresizingMaskIntoConstraints = false
        label.textAlignment = .center
        label.font = UIFont.boldSystemFont(ofSize: 14)
        return label
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Done", style: .plain, target: self, action: Selector(("done")))

        navigationItem.title = "Results"

        view.backgroundColor = UIColor.white

        view.addSubview(resultsLabel)
        view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[v0]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": resultsLabel]))
        view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[v0]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": resultsLabel]))

        let names = ["Ross", "Joey", "Chandler", "Monica", "Rachel", "Phoebe"]

        var score = 0
        for question in QuestionController.questionsList {
            score += question.selectedAnswerIndex!
        }

        let result = names[score % names.count]
        resultsLabel.text = "Congratulations, you'd make a great \(result)!"
    }

    func done() {
        navigationController?.popToRootViewController(animated: true)
    }

}

class QuestionHeader: UITableViewHeaderFooterView {

    override init(reuseIdentifier: String?) {
        super.init(reuseIdentifier: reuseIdentifier)
        setupViews()
    }

    let nameLabel: UILabel = {
        let label = UILabel()
        label.text = "Sample Question"
        label.font = UIFont.boldSystemFont(ofSize: 14)
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()

    func setupViews() {
        addSubview(nameLabel)
        addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-16-[v0]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": nameLabel]))
        addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[v0]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": nameLabel]))
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

}

class AnswerCell: UITableViewCell {

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        setupViews()
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    let nameLabel: UILabel = {
        let label = UILabel()
        label.text = "Sample Answer"
        label.font = UIFont.systemFont(ofSize: 14)
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()

    func setupViews() {
        addSubview(nameLabel)
        addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-16-[v0]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": nameLabel]))
        addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[v0]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": nameLabel]))
    }

}

Upvotes: 0

Views: 267

Answers (2)

odonckers
odonckers

Reputation: 398

As Sh_Khan stated, what you need to do is set a frame. If this is your permanent method, you could also just set constraints. If you set constraints, it will automatically change height and width.

tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
tableView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true

You can add this code into the viewDidLoad function. Basically it's setting a constraint for the left, right, top, and bottom sides of the view that the UIViewController automatically sets. This will force the height and width to change depending on where your left, right, top, and bottom sides are positioned.

Upvotes: 0

Shehata Gamal
Shehata Gamal

Reputation: 100503

The tableView has no frame

tableView = UITableView()

tableView.frame = self.view.bounds  // this for a test change it as you want 

Or use constraints

Upvotes: 1

Related Questions