【问题标题】:Pass data by protocol while using Container to view another ViewController in Swift使用 Container 在 Swift 中查看另一个 ViewController 时通过协议传递数据
【发布时间】:2015-12-11 13:24:19
【问题描述】:

我开始开发this question 应用程序。 我从 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
    }
}

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

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

【问题讨论】:

  • 你从 CategoriesData 开始为 nil。那是怎么改变的? (使用协议很好,但您仍然需要对实现协议的对象的引用。)

标签: swift uiviewcontroller swift2 swift2.1 swift-protocols


【解决方案1】:

已编辑

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


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

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

我可能弄错了,但据我所知,协议委托用于在模型(对于 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 的关键变化,就像您将 UITextFieldDelegate 的固有委托函数用于 UITextField 实例(例如 @987654345 @)。

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

// 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' ...
    }

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-21
    • 2020-05-30
    • 2023-03-08
    • 1970-01-01
    • 2014-07-25
    相关资源
    最近更新 更多