2

我开始研究这个问题应用程序。我从 tableView 的类别开始:

在此处输入图像描述

对于数据交换,我决定使用一个协议:

protocol Category {
    func data(object:AnyObject)
}

在第一个 ViewController 中有以下代码:

class ViewController: UIViewController {

    var items:[String] = ["Desktop","Tablet","Phone"]

    let CategoriesData:Category? = nil

    override func viewDidLoad() {
        super.viewDidLoad()

        CategoriesData?.data(items)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

在第二个 ViewController(Container 中的 tableView)中有如下代码:

class CategoriesViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, Category  {

    @IBOutlet var table: UITableView!

    var items:[String] = []

    func data(object: AnyObject) {
        self.items = (object as? [String])!
        print(object)
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

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

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell:TableViewCell = self.table.dequeueReusableCellWithIdentifier("SegueStage") as! TableViewCell

        cell.nameLabel.text = items[indexPath.row]
        return cell
    }
}

对我来说,显然没关系。但是模拟器上什么也没出现。

在此处输入图像描述

我的问题是:如果容器用来呈现另一个 viewController 作为通过协议传递数据应该做吗?

4

1 回答 1

4

已编辑

我回答了为什么 TO:s 解决方案没有按预期工作,但我刚刚意识到我还没有给出一个可行的答案来说明如何使用协议作为ViewController->ViewController通信的代表。在有人可以更好地回答完整问题之前,我将在下面留下半答案。


在代码中使用的方式protocol中,您将协议定义为type实例Category的委托。当一个类型的实例被初始化——并因此在某个其他类的范围内本地拥有时,该实例可以将回调委托给拥有的类。ViewControllerViewController

问题是您CategoriesViewController不包含任何类型的实例ViewController。我们注意到,这两个类本身都是 的子类UIViewController,但它们都不包含彼此的实例。因此,您CategoriesViewController确实符合协议Category,通过实现协议方法data(...),但没有ViewController实例CategoriesViewController可以对此函数进行回调。因此,您的代码编译文件,但实际上永远不会调用方法data(...)in 。CategoriesViewController

我可能弄错了,但据我所知,协议委托用于在模型(对于 MVC 设计中的模型)和控制器(参见下面的示例)之间进行回调,而在您的情况下,您希望直接在两个控制器之间进行委托。


作为模型-委托-控制器设计的示例,考虑一些自定义用户控件,具有一些关键属性value(例如评级控件中的位置),实现为以下子类UIView

// CustomUserControl.swift
protocol CustomUserControlDelegate {
    func didChangeValue(value: Int)
}

class CustomUserControl: UIView {

    // Properties
    // ...
    private var value = 0 {
        didSet {
            // Possibly do something ...

            // Call delegate.
            delegate?.didChangeValue(value)
        }
    }

    var delegate: CustomUserControlDelegate?

    // ... some methods/actions associated with your user control.
}

现在让我们假设您的一个实例CustomUserControl在视图控制器中使用,例如ViewController. 自定义控件的委托函数可以在视图控制器中用于观察模型中的关键变化CustomUserControl,就像您使用UITextFieldDelegateforUITextField实例(例如textFieldDidEndEditing(...))的固有委托函数一样。

对于这个简单的例子,使用didSet类属性的委托回调value来告诉视图控制器它的一个出口已经关联了模型更新:

// ViewController.swift
Import UIKit
// ...

class ViewController: UIViewController, CustomUserControlDelegate {

    // Properties
    // ...
    @IBOutlet weak var customUserControl: CustomUserControl!
        // Instance of CustomUserControl in this UIViewController

    override func viewDidLoad() {
        super.viewDidLoad()
        // ...

        // Custom user control, handle through delegate callbacks.
        customUserControl.delegate = self
    }

    // ...

    // CustomUserControlDelegate
    func didChangeValue(value: Int) {
        // do some stuff with 'value' ...
    }

}
于 2015-12-11T14:46:41.160 回答