UITableView与控制器分开ViewController [英] UITableView with controller separate from ViewController

查看:93
本文介绍了UITableView与控制器分开ViewController的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Swift和XCode的新手,今年夏天参加iOS开发课程。我们正在做的许多项目和我正在看到的用于UI元素(如PickerViews,TableViews等)的示例正在定义ViewController.swift文件中的所有内容,该文件充当主视图的控制器。这工作正常,但我开始达到项目复杂性的地步,我真的希望我的所有代码都不会被塞进同一个Swift文件中。我和一位做过iOS开发的朋友谈过,他说这是理智且合理的,并且与正确的面向对象编程完全一致......但我似乎无法让它发挥作用。通过反复试验我已经遇到了这种情况:应用程序在模拟器中运行,UITableView出现,但我没有填入条目。当所有代码都在ViewController中时,我可以正常工作,但是一旦我开始尝试创建一个新的控制器类并使该类的实例成为UITableView的dataSource / delegate,我就什么也得不到。我觉得我要么缺少对Swift的核心理解,要么在XCode中对Interface Builder做错了。

I'm a newbie to Swift and XCode, taking a class in iOS development this summer. A lot of projects we're doing and examples I'm seeing for UI elements like PickerViews, TableViews, etc. are defining everything in the ViewController.swift file that acts as the controller for the main view. This works fine, but I'm starting to get to the point of project complexity where I'd really like all of my code to not be crammed into the same Swift file. I've talked to a friend who does iOS development on the side, he said this is sane and reasonable and well in-line with proper object-oriented programming... but I just can't seem to get it to work. Through trial and error I've gotten to this situation: the app runs in the simulator, the UITableView appears, but I'm not getting it populated with entries. I can get it working just fine when all the code is in the ViewController, but once I start trying to create a new controller class and make an instance of that class the dataSource/delegate of the UITableView I start getting nothing. I feel like I'm either missing some core understanding of Swift here, or doing something wrong with the Interface Builder in XCode.

我的最终结果应该是一个带有三个的UITableView其中的条目;目前我正在获得一个没有条目的UITableView。我正在关注一些我用Google搜索的不同示例,但主要是另一个问题: UITableView示例for Swift

My end result should be a UITableView with three entries in it; currently I'm getting a UITableView with no entries. I'm following along with a few different examples I've Googled, but primarily this other SO question: UITableView example for Swift

ViewController.swift:

ViewController.swift:

import UIKit

class ViewController: UIViewController{

    @IBOutlet var stateTableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()
        var viewController = StateViewController()
        self.stateTableView.delegate = viewController
        self.stateTableView.dataSource = viewController
    }
}

StateViewController.swift:

StateViewController.swift:

import UIKit

class StateViewController: UITableViewController{
    var states = ["Indiana", "Illinois", "Nebraska"]

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
    {
        return states.count;
    }

    func tableView(cellForRowAttableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
    {
        let cell = UITableViewCell(style:UITableViewCellStyle.default, reuseIdentifier:"cell")
        cell.textLabel?.text = states[indexPath.row]
        return cell
    }
}

在XCode中,我将UITableView连接到View控制器;出口设置为 dataSource 委托,引用出口为 stateTableView

In XCode I have the UITableView hooked up to the View Controller; the outlets are set to dataSource and delegate and the referencing outlet is stateTableView.

我没有收到任何错误;我在ViewController.swift中的`var viewController = StateViewController()'语句中得到警告,它要求我使用常量,但将其切换为常量不会改变行为(这是应该的,我应该是假设)。

I'm not getting any errors; I do get a warning on my `var viewController = StateViewController()' statement in ViewController.swift where it wants me to use a constant, but switching it to a constant doesn't change the behavior (this is as it should be, I assume).

最初我假设错误发生在我的StateViewController.swift文件中,我没有创建一个符合UITableViewDataSource或UITableViewDelegate协议的对象,但是如果我甚至将它们添加到类声明中,我会立即得到诸如StateViewController'与协议'UITableViewDataSource'的冗余一致性之类的错误 - 我正在读这是因为从UITableViewController继承也会自动继承其他协议。

Originally I assumed that the error was in my StateViewController.swift file, where I'm not creating an object that adheres to the UITableViewDataSource or UITableViewDelegate protocol, but if I even add them into the class statement I immediately get errors like "Redundant conformance of 'StateViewController' to protocol 'UITableViewDataSource'" - I'm reading that this is because inheriting from UITableViewController automatically inherits the other protocols as well.

我尝试的最后一件事是在StateViewController的tableView函数中引用 self.states ,但我很确定自己在Swift中的工作方式与在Python中的工作方式相同,感觉就像我只是想尝试一样dd神奇的话在这一点上。

The last thing I tried was instead referring to self.states in the StateViewController's tableView functions, but I'm pretty sure self in Swift works the same as it does in Python and it feels like I'm just trying to add magic words at this point.

我已经调查过我目前有限的Swift知识可以带我,所以任何解释什么的答案我做错了而不仅仅是告诉我要解决的问题会非常感激。

I've investigated as far as my currently-limited Swift knowledge can take me, so any answer that explains what I'm doing wrong rather than just telling me what to fix would be very appreciated.

推荐答案

你的问题正在引起通过内存管理问题。您有以下代码:

Your issue is being caused by a memory management problem. You have the following code:

override func viewDidLoad() {
    super.viewDidLoad()
    var viewController = StateViewController()
    self.stateTableView.delegate = viewController
    self.stateTableView.dataSource = viewController
}

考虑 viewController 变量的生命周期。当达到 viewDidLoad 的结尾时结束。由于表视图的 dataSource 委托属性为 ,一旦 viewDidLoad 结束,就没有强烈的参考来保持你的 StateViewController 活着。由于弱引用,结果是表视图的 dataSource 委托属性恢复为 nil viewDidLoad 结束后。

Think about the lifetime of the viewController variable. It ends when the end of viewDidLoad is reached. And since a table view's dataSource and delegate properties are weak, there is no strong reference to keep your StateViewController alive once viewDidLoad ends. The result, due to the weak references, is that the dataSource and delegate properties of the table view revert back to nil after the end of viewDidLoad is reached.

解决方案是创建对 StateViewController 的强引用。通过向视图控制器类添加属性来执行此操作:

The solution is to create a strong reference to your StateViewController. Do this by adding a property to your view controller class:

class ViewController: UIViewController{
    @IBOutlet var stateTableView: UITableView!
    let viewController = StateViewController()

    override func viewDidLoad() {
        super.viewDidLoad()

        self.stateTableView.delegate = viewController
        self.stateTableView.dataSource = viewController
    }
}

现在你的代码将起作用。

Now your code will work.

一旦你开始工作,请回答Ahmed F的答案。你的 StateViewController class应该是一个视图控制器。它在任何意义上都不是视图控制器。它只是一个实现表视图数据源和委托方法的类。

Once you get that working, review the answer by Ahmed F. There is absolutely no reason why your StateViewController class should be a view controller. It's not a view controller in any sense. It's simply a class that implements the table view data source and delegate methods.

这篇关于UITableView与控制器分开ViewController的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆