使用容器查看Swift中的另一个ViewController时,按协议传递数据
我开始开发这个应用程序。 我从类别的表格视图开始: 对于数据交换,我决定使用协议:使用容器查看Swift中的另一个ViewController时,按协议传递数据,swift,uiviewcontroller,swift2,swift2.1,swift-protocols,Swift,Uiviewcontroller,Swift2,Swift2.1,Swift Protocols,我开始开发这个应用程序。 我从类别的表格视图开始: 对于数据交换,我决定使用协议: protocol Category { func data(object:AnyObject) } 在第一个视图中,控制器具有以下代码: class ViewController: UIViewController { var items:[String] = ["Desktop","Tablet","Phone"] let CategoriesData:Category? = ni
protocol Category {
func data(object:AnyObject)
}
在第一个视图中,控制器具有以下代码:
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.
}
}
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中,容器中的tableView具有以下代码:
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.
}
}
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表示为通过协议传递数据,那么应该这样做吗?
我回答了为什么TO:s解决方案不能按预期工作,但我刚刚意识到,对于如何使用协议作为ViewController->ViewController通信的代理,我还没有给出一个可行的答案。我将在下面留下半个答案,直到有人能够更好地回答完整的问题
按照在代码中使用协议的方式,您可以将协议类别定义为ViewController类型实例的委托。当ViewController类型的实例在某个其他类中初始化并因此在其作用域中本地拥有时,该实例可以将回调委托给所属类
问题是您的CategoriesViewController不包含任何ViewController类型的实例。我们注意到,这两个类本身都是UIViewController的子类,但它们都不包含彼此的实例。因此,通过实现协议方法data…,您的CategoriesViewController确实符合协议类别,但CategoriesViewController中没有可以回调此函数的ViewController实例。因此,您的代码编译文件,但实际上,方法数据。。。在CategoriesViewController中,将永远不会调用
我可能弄错了,但据我所知,协议委托用于在MVC设计中的模型和控制器的模型之间进行回调(见下面的示例),而在您的情况下,您希望在两个控制器之间直接使用委托
作为模型委托控制器设计的一个例子,考虑一些自定义用户控件,其中一些关键属性值,例如在分级控件中的位置,被实现为UIVIEW的子类:
现在让我们假设CustomUserControl的一个实例用于视图控制器,例如ViewController。自定义控件的委托函数可在视图控制器中用于观察CustomUserControl模型中的关键更改,就像您将UITextFieldDelegate的固有委托函数用于UITextField实例一样,例如TextFieldDiEndEditing 对于这个简单的示例,使用来自类属性值的didSet的委托回调来告诉视图控制器它的一个出口已经关联了模型更新:// 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' ...
}
}
首先,CategoriesData为nil。这有什么变化吗?使用协议是可以的,但仍然需要对实现协议的对象的引用。