简体   繁体   English

iOS-UIView内的UITableView

[英]iOS - UITableView inside a UIView

I want to display a UITableView inside a UIViewController . 我想在UIViewController显示一个UITableView This View Controller contains a UISegmentedControl with two screens ( FirstViewController and SecondViewController ). 该视图控制器包含一个带有两个屏幕的UISegmentedControlFirstViewControllerSecondViewController )。

The first View Controller is the one that contains the UIViewTable (please don't mind the second). 第一个视图控制器是包含UIViewTable视图控制器(请不要介意第二个)。

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 . 当我在模拟器中执行应用程序时,一切正常, 但是当我尝试在第一个ViewController中滚动表格视图时,单元格消失了 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. 我是iOS开发的新手(我来自Android),显然这里缺少一些东西。

I already tried adding a UIViewTable outside a container UIView and it works fine. 我已经尝试过将UIViewTable添加到容器UIView之外,并且工作正常。 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). 带有UISegmentedControlUIView UIViewController (将包含分段控件的两个屏幕)。

  • 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文件和一个xib文件,并具有用于表单元格的两个文件Cell.swiftCell.xib

FirstViewController.swift 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 FirstViewController.xib

在此处输入图片说明

Cell.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. 一个明显的问题是,您说的是container.addSubview(v)却没有给v任何框架或约束。 Since you use autolayout to position container , you ought to use autolayout to position v as well. 由于您使用自动布局来定位container ,因此您也应该使用自动布局来定位v You should set its top, bottom, leading, and trailing anchors to equal those of container with a constant of zero. 您应该将其顶部,底部,前导和尾随锚设置为等于containerconstant ,且constant为零。 (And set its translates... to false .) Do that for both cases of v in the loop. (然后将其translates...设置为false 。)对于循环中两种v的情况都应这样做。

However, there is much more serious problem, which is that the view controllers that you create by saying FirstViewController() and SecondViewController() are not retained. 但是,还有一个更严重的问题,那就是不保留通过FirstViewController()SecondViewController()创建的视图控制器。 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). 您必须使视图控制器成为父视图控制器(在这种情况下为Item)的视图控制器。 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:- 这段代码是针对UITableViewCell类的:

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
    }

}

我的表格视图

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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