2017-07-06 80 views
2

Edit: Please note the question below discusses using delegation between 2 viewcontrollers that are also implemented in a UITabBarController.Swift代表团:意外地发现零,同时展开一个可选值

我已经在这里和YouTube上进行了一些搜索,但没有看到我的问题在其他地方复制。我会保持这一点。

我有编码自己-not通过XCode-产生2个视图控制器; TabOneController和TabTwoController

下面

对于两个编码...

import UIKit 

class TabOneController: UIViewController{ 


    private let instanceOfTabOneView = TabOneView() 

    var vc1Delegate: fromOneToTwo! 

    override func loadView() { 

     super.loadView() 

      view.addSubview(instanceOfTabOneView.buildTheVu()) 
       view.backgroundColor = UIColor.white 

     runThisOnce() 

     } 

    func runThisOnce(){ 

     vc1Delegate.passTheValue(heroNameIs: "pass this to TabTwoController") 

    } 

} 

protocol fromOneToTwo{ 

    func passTheValue(heroNameIs: String) 

} 

为标签2 ...

import UIKit 

class TabTwoController: UIViewController, fromOneToTwo{ 


    private let instanceOfTabTwoView = TabTwoView() 


    override func loadView() { 

     super.loadView() 

      view.addSubview(instanceOfTabTwoView.buildTheVu()) 

     assignDelegateToSelf() 

    } 

    func assignDelegateToSelf(){ 

     let instanceTabOne = TabOneController() 
      instanceTabOne.vc1Delegate = self 

    } 

    func passTheValue(heroNameIs:String){ 

     instanceOfTabTwoView.txtFld.text = heroNameIs 

    } 

} 

我得到以下运行时错误-The应用程序构建成功 - ...

fatal error: unexpectedly found nil while unwrapping an Optional value

onfollo翼行...

vc1Delegate.passTheValue(heroNameIs: "pass this to TabTwoController") 

当我注释掉上面的行,应用程序构建和运行成功,但当然应用程序不执行的代表团。

我有点明白什么是编译器试图告诉我,那

vc1Delegate 

尚未实例-I guess-。但我在每一块岩石下搜寻,似乎无法找到如何解决这个问题。

我会很感激的任何帮助或指导。对不起,如果我的代码看起来不成熟,我是Swift和编程的新手。谢谢。

回答

1

UITabBarController,所述第一接线片被默认实例。视图控制器初始化执行loadView并且发现nil因为第二片还不初始化;这是正常的行为。我的建议是做委托弱可选与?后缀和其他地方运行委托代码。另外,请始终将类和协议名称中的第一个字母大写。

weak var vc1Delegate: FromOneToTwo? 

如果这种结构是强制性的,尝试用自定义通知观察者来代替。

+0

感谢您的答复。我将用2个常规ViewController创建一个Xcode项目,并用变量替换所有UI控件。如果UITabController是问题,我会发布另一条评论。谢谢你的时间。 –

1

首先,您的错误发生在var vc1Delegate: fromOneToTwo!行中,而您将此委托变量声明为非空,但对其调用passTheValue。正确的做法将是

var vc1Delegate: fromOneToTwo? 

func runThisOnce(){ 
    if let delegate = vc1Delegate { 
     vc1Delegate.passTheValue(heroNameIs: "pass this to TabTwoController") 
    } 
} 

其次,你没有正确使用委托。在assignDelegateToSelf()函数中,您正在创建一个新实例TabOneController ,然后分配委托。相反,您需要找出现有的TabOneController实例并分配委托。

+0

如何找出现有的'TabOneController'实例? – Sebastian

+0

@Sebastian这取决于你的代码如何写入...如果你想要委托调用,你必须为控制器注册委托,然后你只能接收来自该控制器的委托调用。通常情况下,如果使用storyboard和正常的segue到新的视图控制器,则不需要关心它,因为您只有一个视图控制器实例。但是,当您以编程方式创建视图控制器(如从故事板功能调用初始化)时,则只需启动一次并将该瞬间存储在某处,以便稍后可以找到并接收呼叫。 –

+0

感谢您的解释。我能够做到这一点,当segue被触发时,将当前的viewcontroller类保存在变量中,然后在该segue期间将该变量传递给其他视图控制器 – Sebastian

相关问题