简体   繁体   中英

iOS - UITableView inside a UIView

I want to display a UITableView inside a UIViewController . This View Controller contains a UISegmentedControl with two screens ( FirstViewController and SecondViewController ).

The first View Controller is the one that contains the UIViewTable (please don't mind the second).

When I execute the app in the simulator, everything works fine, but when I try to scroll the table view in the first ViewController, the cells disappear . The only way to make them reappear is to kill the app and reopen it again.

I'm new to iOS development (I come from Android), and I'm obviously missing something here.

I already tried adding a UIViewTable outside a container UIView and it works fine. So I'm guessing the problem has to do with the container or the segmented control...

Here's my implementation:

  • Storyboard

故事板配置 UIViewController with UISegmentedControl and UIView (which will contain the two screens of the segmented control).

  • View Controller

     @IBOutlet weak var container: UIView! var sectionViews:[UIView]! override func viewDidLoad() { super.viewDidLoad() sectionViews = [UIView]() sectionViews.append(FirstViewController().view) sectionViews.append(SecondViewController().view) for v in sectionViews { container.addSubview(v) } container.bringSubviewToFront(sectionViews[0]) } @IBAction func switchViewsAction(_ sender: UISegmentedControl) { self.container.bringSubviewToFront(self.sectionViews[sender.selectedSegmentIndex]) } 
  • First View Controller

The FirstViewController has a swift and a xib files, and has two files Cell.swift and Cell.xib for the table cell.

FirstViewController.swift

@IBOutlet weak var tableView: UITableView!
let cellID = "CellId"

override func viewDidLoad() {
    super.viewDidLoad()

    self.tableView.register(UINib(nibName: "Cell", bundle: nil), forCellReuseIdentifier: cellID)
    self.tableView.dataSource = self
    self.tableView.delegate = self
}

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

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = self.tableView.dequeueReusableCell(withIdentifier: cellID, for: indexPath) as! Cell
    cell.label.text = "\(indexPath.row)"
    return cell
}

FirstViewController.xib

在此处输入图片说明

Cell.xib

在此处输入图片说明

Any help will be appreciated! Thanks

One obvious problem is that you are saying container.addSubview(v) without giving v any frame or constraints. Since you use autolayout to position container , you ought to use autolayout to position v as well. You should set its top, bottom, leading, and trailing anchors to equal those of container with a constant of zero. (And set its translates... to false .) Do that for both cases of v in the loop.

However, there is much more serious problem, which is that the view controllers that you create by saying FirstViewController() and SecondViewController() are not retained. Therefore they vanish in a puff of smoke. They thus lose their functionality; for example, the table view no longer has any data source or delegate so it has no cells.

What you are doing is totally illegal. You cannot simply use a view controller to "dumpster-dive" as a way of grabbing its view and shove its view, willy-nilly, into the interface. You must make the view controller a child view controller of your parent view controller (Item in this case). There is an elaborate dance you must do in order to ensure that the child view controller has its proper place in the view controller hierarchy and receives in good order all the messages that a view controller must receive, and you are not doing the dance.

For examples of how to do the dance, see for instance my answers

and

import UIKit

class TestViewController: UIViewController , UITableViewDataSource, UITableViewDelegate{

    @IBOutlet weak var segmentControlOutlet: UISegmentedControl!
    @IBOutlet weak var tableView: UITableView!
    var arrayName = ["Label1", "Label2", "Label3","Label4","Label5","Label6","Label7","Label8","Label9","Label10"]
    var arrayName2 =  ["Label1", "Label2", "Label3","Label4","Label5"]

    override func viewDidLoad() {
        super.viewDidLoad()

    }

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

    @IBAction func segmentControlAction(_ sender: UISegmentedControl) {
        self.tableView.reloadData()
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if segmentControlOutlet.selectedSegmentIndex == 0 {
            return arrayName.count

        }else{
            return arrayName2.count

        }
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "TestTableViewCell", for: indexPath) as! TestTableViewCell
        if segmentControlOutlet.selectedSegmentIndex == 0 {
            cell.textLabel?.text = arrayName[indexPath.row]

        }else{
             cell.textLabel?.text = arrayName2[indexPath.row]
        }
        return cell
    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 50
    }
}

And this code is for UITableViewCell Class:-

import UIKit

class TestTableViewCell: UITableViewCell {
    @IBOutlet weak var labelName: UILabel!

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

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

        // Configure the view for the selected state
    }

}

我的表格视图

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM