Andrew
Andrew

Reputation: 2157

Problem with adding tableview into tableview cell swift

I would like to show table view with cell where will be one label and tableview below this label. I have such layout right now:

enter image description here

view above my tables view will be hidden in some conditions so as a result I will have table view on whole screen. So... I found this video where developer managed to solve my task. I did everything similarly to his video but I didn't manage to show table view inside table view cell. Here is my steps:

  1. Added all views to general view.
  2. Attached tags to my table views: 100 for main table view and 90 for inside table view.
  3. Created cell classes and attached them to both cells.
  4. Added extension at main cell like in video.
  5. Handled table view tag in main view controller.

As I see the problem is with inside table view which can't be shown. Below you can see classes for cells. Main cell:

class GeneralCell : UITableViewCell {
    @IBOutlet weak var answerOptions: UITableView!
    @IBOutlet weak var questionText: UILabel!
}

extension GeneralCell{
    func setTableViewDataSourceDelegate <D:UITableViewDelegate & UITableViewDataSource> (_ dataSourceDelegate: D, forRow row: Int)
    {
        answerOptions.delegate = dataSourceDelegate
        answerOptions.dataSource = dataSourceDelegate
        
        answerOptions.reloadData()
    }
}

inside cell:

class AnswersCell: UITableViewCell {
    @IBOutlet weak var answerOption: UILabel!
}

and here is my view controller:

class PollsController: UIViewController, UITableViewDataSource,UITableViewDelegate {

    @IBOutlet weak var questionTableView: UITableView!
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        
        questionTableView.delegate = self
        questionTableView.dataSource = self
        
    }
    

    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
         return 1
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        print(tableView.tag)
        if tableView.tag == 100 {
            let cell: GeneralCell = tableView.dequeueReusableCell(withIdentifier: "GeneralCell") as! GeneralCell
            cell.answerOptions.reloadData()
            return cell
        }else{
            let cell: AnswersCell = tableView.dequeueReusableCell(withIdentifier: "AnswersCell") as! AnswersCell
            return cell
        }
    }
    
    func numberOfSections(in tableView: UITableView) -> Int {
        if tableView.tag == 100 {
            return 1
        }else{
            return 6
        }
    }
}

Then I did some test for getting to know where the problem is. I added print() into data loader function:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        print(tableView.tag)
        if tableView.tag == 100 {
            print("1")
            let cell: GeneralCell = tableView.dequeueReusableCell(withIdentifier: "GeneralCell") as! GeneralCell
            cell.answerOptions.reloadData()
            return cell
        }else{
            print("2")
            
            let cell: AnswersCell = tableView.dequeueReusableCell(withIdentifier: "AnswersCell") as! AnswersCell
            return cell
        }
    }

and in the output I saw only one tag:

100

and as I see inside table view can't be loaded but I can't understand why. Maybe someone of you will find problem or mistake?

Upvotes: 0

Views: 1774

Answers (2)

Nikunj Kumbhani
Nikunj Kumbhani

Reputation: 3924

Try this

class GeneralCell : UITableViewCell {
    @IBOutlet weak var answerOptions: UITableView!
    @IBOutlet weak var questionText: UILabel!
}



func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        print(tableView.tag)
        if tableView == questionTableView{
            let cell: GeneralCell = tableView.dequeueReusableCell(withIdentifier: "GeneralCell") as! GeneralCell
            cell.answerOptions.delegate = self
            cell.answerOptions.dataSource = self
            cell.answerOptions.reloadData()
            return cell
        }else{
            let cell: AnswersCell = tableView.dequeueReusableCell(withIdentifier: "AnswersCell") as! AnswersCell
            return cell
        }
    }

Upvotes: 1

aiwiguna
aiwiguna

Reputation: 2922

I suggest you use only one tableview, here some example

struct Answer {
    let answerText: String
}

struct Question {
    let questionText: String
    let answers: [Answer]
}

class ViewController: UIViewController {
    
    @IBOutlet weak var tableView: UITableView!
    var questions: [Question] = []
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        for i in 1...10 {
            let question = Question(questionText: "Question \(i)", answers: [
                Answer(answerText: "Answer 1 Question \(i)"),
                Answer(answerText: "Answer 2 Question \(i)"),
                Answer(answerText: "Answer 3 Question \(i)"),
                Answer(answerText: "Answer 4 Question \(i)")
            ])
            questions.append(question)
        }
        tableView.dataSource = self
        tableView.delegate = self
        tableView.sectionHeaderHeight = UITableView.automaticDimension;
        tableView.estimatedSectionHeaderHeight = 44
    }
    
    
}

extension ViewController: UITableViewDataSource, UITableViewDelegate {
    func numberOfSections(in tableView: UITableView) -> Int {
        return questions.count
    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return questions[section].answers.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "AnswerCell", for: indexPath) as! AnswerCell
        
        cell.answerLabel.text = questions[indexPath.section].answers[indexPath.row].answerText
        return cell
    }
    
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let cell = tableView.dequeueReusableCell(withIdentifier: "QuestionCell") as! QuestionCell
        
        cell.questionLabel.text = questions[section].questionText
        return cell
    }
}

enter image description here

Upvotes: 2

Related Questions