在没有情节提要的情况下使用 UITableView

Posted

技术标签:

【中文标题】在没有情节提要的情况下使用 UITableView【英文标题】:Using UITableView without a storyboard 【发布时间】:2014-11-09 13:28:51 【问题描述】:

我正在尝试将 tableView 设置为我的 viewController 中的子视图。但不使用情节提要!我正在尝试这段代码,但它似乎不起作用,我不明白为什么.. 所以这是应该在其中创建 tableview 的代码:

func TableView(position: CGRect, allRecipes: [Recipe]) -> UITableView 
    let tableView: UITableView = UITableViewForAllRecipes(style: UITableViewStyle.Plain).tableView


    return tableView;

.

这是我的 tableviewcontroller (UITableViewForAllRecipes)

class UITableViewForAllRecipes: UITableViewController 

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
    var cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "cell")

    cell.textLabel.text = "ok"

    return cell


override func numberOfSectionsInTableView(tableView: UITableView) -> Int 
    println("nosit")
    return 1


override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    println("tv")
    return 3

有人看到我做错了吗?因为它似乎甚至没有打印那些“nosit”和“tv”,所以它没有达到那个代码..我也没有从调试中得到任何东西..

【问题讨论】:

TableView函数返回后,UITableViewForAllRecipes视图控制器将被释放。 @Swipesight 当我移动代码以便直接将 tableview 添加为我的 viewController 的子视图时,它仍然是空的并且没有到达我控制器中的 println-code 基本上你不应该这样创建表视图,从TableView函数返回的表视图将有它的数据源和委托指向被释放的视图控制器。 【参考方案1】:

如何实现将表视图添加到其视图层次结构的视图控制器取决于您是否需要单独的视图控制器来管理表视图。

如果您确实需要单独的视图控制器,那么

class UITableViewForAllRecipes: UITableViewController 

        override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
                var cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "cell")

                cell.textLabel.text = "ok"

                return cell
        

        override func numberOfSectionsInTableView(tableView: UITableView) -> Int 
                println("nosit")
                return 1
        

        override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
                println("tv")
                return 3
        


class ViewController: UIViewController 
        let childTableViewController = UITableViewForAllRecipes(style: .Plain)
        let otherView = UIView()

        override func viewDidLoad() 
                super.viewDidLoad()

                // TODO: setup otherView's frame, autoresizingMask ...

                view.addSubview(otherView)

                addChildViewController(childTableViewController)

                let tableView = childTableViewController.tableView

                // TODO: setup tableView's frame, autoresizingMask ...

                view.addSubview(tableView)

                childTableViewController.didMoveToParentViewController(self)
        

否则

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate 
        let tableView = UITableView()
        let otherView = UIView()

        override func viewDidLoad() 
                super.viewDidLoad()

                // TODO: setup otherView's frame, autoresizingMask ...

                view.addSubview(otherView)

                // TODO: setup tableView's frame, autoresizingMask ...

                tableView.dataSource = self
                tableView.delegate = self

                view.addSubview(tableView)
        

        // MARK: - UITableViewControllerDataSource

        func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
                var cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "cell")

                cell.textLabel.text = "ok"

                return cell
        

        func numberOfSectionsInTableView(tableView: UITableView) -> Int 
                println("nosit")
                return 1
        

        func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
                println("tv")
                return 3
        

【讨论】:

【参考方案2】:

@Swipesight 是对的。看到空tableview的原因:

您创建了一个 UITableViewForAllRecipes 实例,tableview 控制器拥有一个 tableview 和它自己作为该 tableview 的数据源和委托。 然后您抓取 tableview,将其添加为子视图,但由于 tableview 将其委托作为弱引用,当您退出 TableView() func 时,tableviewcontroller 本身被释放,因为没有更多的强引用。 当 tableview 被渲染时,它会询问它的数据源,它是 nil,你会得到一个空的 table view。

可能的修复:

在父视图控制器中对 tableviewcontroller 进行强引用

例如

func TableViewController(position: CGRect, allRecipes: [Recipe]) -> UITableViewForAllRecipes 
    return UITableViewForAllRecipes(style: UITableViewStyle.Plain)

在你的父视图控制器中添加一个属性

var tableViewController: UITableViewForAllRecipes?

然后在你调用 TableView 的函数中

self.tableViewController = self.TableViewController(xxxx)
self.view.addSubview(self.tableViewController!.tableView)

【讨论】:

好吧,我现在明白为什么它在显示时是空的,但我不明白为什么它在调试时仍然没有到达代码,以及我如何能够保持那个强大的 ref。也许我当然看错了,还有其他方法可以在我的主视图中获得填充的表格视图吗? @Shuo 添加子视图时,需要确保事件继续分发到两个视图控制器。为此,您可以将新的视图控制器显式关联为容器的子级。 - 摘自 Apple 的“ios 视图控制器编程指南” @JayEss 你是在构建一个容器视图控制器,它有一个表视图控制器作为子视图,还是只想以编程方式构建一个表视图控制器? @Swipesight 第一个。我试图做的是几乎有一个包含一个表视图作为子视图的视图。所以不要使用 tableview 作为主视图。当然,要显示一张已填满的表格,而不是一张空白的表格

以上是关于在没有情节提要的情况下使用 UITableView的主要内容,如果未能解决你的问题,请参考以下文章

使用情节提要在 UItableview 上浮动按钮

带有自定义单元格的 ViewController 内的 UITableView 没有情节提要

使用 Swift 在没有情节提要的情况下展开 segue

如何在没有情节提要的情况下设置 ViewController 的框架

如何在没有情节提要的情况下使用按钮切换视图?

如何在没有情节提要的情况下以编程方式实例化视图控制器