swift - 从非父视图控制器分配委托
问题描述
我在 Swift 4 中的协议和委托方面有点挣扎。我将尽我所能描述/向你展示我所拥有的。
主视图控制器:(MVC) 1. 我有主视图控制器类(MVC)。VC 具有我想从另一个 ViewController 类 (AVC) 访问的选项属性
class ViewController: UIViewController {
var options: Options?
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "To Statements") {
// pass data to next view
let vc = segue.destination
let statementVC = vc as! StatementsViewController
statementVC.coreDataStack = coreDataStack
statementVC.currentPerson = currentPerson
}
}
extension ViewController: FormateStatementDelegate {
// formatting protocol
func addStatementFormat() -> Int {
// here is where I would use the options var that is found in the (MVC)
}
}
Statement ViewController: (SVC) 2. 我有一个从 (MVC) 调用的 View Controller 类 Statement ViewController (SVC)。我正在使用prepare for segue func来设置这个视图控制器(MVC)。
class StatementsViewController: UIViewController{
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "Add Statement") {
// pass data to next view
//print("segue to add statement")
let vc = segue.destination
let addStatementVC = vc as! AddStatementViewController
addStatementVC.coreDataStack = coreDataStack
addStatementVC.personName = currentPerson!.name!
}
}
AddStatement View Controller (AVC) 3. 我有第三个 View Controller 类 AddStatement View Controller (AVC),它是从 (SVC) 调用的。我也使用prepare for segue func来设置这个视图控制器以及(SVC)
这个类有一个我在 (MVC) 中定义的协议。
protocol FormateStatementDelegate {
func func addStatementFormat() -> Intmal
}
class AddStatementViewController: UIViewController{
var delegate FormateStatementDelegate! = nil
}
我感到困惑的是在哪里设置委托属性。我见过的例子似乎在准备 seguer 函数中设置了委托属性。但是由于 (MVC) 是符合 FormateStatementDelegate 协议的协议,我将在哪里以及如何在 (AVC) 中设置委托,因为它们没有父/子关系。我希望我已经以有意义的方式解释了这一点。
解决方案
您的委托被声明为隐式展开的可选:
class AddStatementViewController: UIViewController{
var delegate FormateStatementDelegate! = nil
}
小心点。如果您忘记设置委托,应用程序将崩溃。强大的保留周期也可能导致内存泄漏。我使用的一般模式是将其声明为弱可选:
protocol FormateStatementDelegate: class {
...
}
class AddStatementViewController: UIViewController{
weak var delegate: FormateStatementDelegate?
func doSomething() {
delegate?.addStatementFormat() // This statement will do nothing if delegate is nil
}
}
现在解决您的问题:如果我正确理解了您的问题描述,则 segue 顺序如下:
ViewContorller -> StatementViewController -> AddStatementViewController
并且AddStatementViewController
有一个代表,它ViewController
符合。您只需要MainViewController
在第二个视图控制器中保存对实例的引用:
class ViewController: UIViewController {
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "To Statements") {
// pass data to next view
let vc = segue.destination
let statementVC = vc as! StatementsViewController
statementVC.coreDataStack = coreDataStack
statementVC.currentPerson = currentPerson
statementVC.formateStatementDelegate = self
}
}
}
class StatementViewController {
weak var formateStatementDelegate: FormateStatementDelegate?
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "Add Statement") {
// pass data to next view
//print("segue to add statement")
let vc = segue.destination
let addStatementVC = vc as! AddStatementViewController
addStatementVC.coreDataStack = coreDataStack
addStatementVC.personName = currentPerson!.name!
addStatementVC.delegate = formateStatementDelegate
}
}
}
推荐阅读
- postgresql - \crosstabview 在 PSQL 命令行中有效,但在 PGADMIN 中无效
- excel - 在 excel 文件中查找和替换,然后用 Excel 应用程序打开它
- django - Django 支付指南
- python - 对出现次数最多的唯一值的唯一值进行分组 Python
- c# - itextSharp C#中的特殊字符
- ios - NSFileManager 的 createFileAtPath 方法有时在 13.3 中返回 false。*
- json - 角度形式数据到 json 对象
- python - 在 Django RestFrameWork 中设置的模型视图中的图像水印
- javascript - 搜索功能可在仪表板的多个图表中搜索特定图表
- scala - Scala:从 Vector( tuples(Int,Int) , ...) 中删除重复的整数