我不断从其他视图更改标签文本时不断遇到此错误

时间:2019-02-21 12:23:50

标签: ios swift mobile fatal-error

感谢您的帮助。 我是Ios开发的新手,我正在尝试更改位于我的第一个初始视图控制器中的标签文本。我希望在按下第二个视图控制器中的一个按钮时更改此文本,该按钮与第一个视图控制器紧密相连。

这是我的第一个视图控制器

import UIKit

protocol gameModeDelegate {
    func didTapChoice(test:String)

}

class ViewController2: UIViewController {
    var selectionDelegate:gameModeDelegate!

    @IBAction func chooseButton(_ sender: Any) {

        selectionDelegate.didTapChoice(test: "TEST")

        let selectVC = storyboard?.instantiateViewController(withIdentifier: "VC1") as! ViewController

        present(selectVC,animated: true,completion: nil)            

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

这是我在第二个标签为

的地方所做的
override func viewDidLoad() {
        super.viewDidLoad()
            let selectVC2 = storyboard?.instantiateViewController(withIdentifier: "VC1") as! ViewController2
            selectVC2.selectionDelegate = self

            winningLabel.isHidden = true
            winningLabel.center = CGPoint(x: winningLabel.center.x, y: winningLabel.center.y - 400)
      playAgainoutlet.isHidden = true
            playAgainoutlet.center = CGPoint(x: playAgainoutlet.center.x, y: playAgainoutlet.center.y + 400)
    }
extension ViewController: gameModeDelegate{
        func didTapChoice(test: String) {
            CommunicationLabel.text = test
        }



    }

到目前为止,我尝试了这两种方法,并且不断出现此错误。

线程1:致命错误:在展开可选值时意外发现nil

1 个答案:

答案 0 :(得分:0)

您不应使用此方法来获得结果,可以使用两种不同的方法来获得相同的结果。

1-使用委托协议方法: 在 secondViewController 中,您应该声明这样的协议

protocol applySelecction {
    func applyText(text: String)
}

,并在类中声明这样的变量。

var delegate: apply selection?

然后在按钮操作中

@IBAction func saveButtom(sender: UIButton){
    //print(selected)
    delegate?.applySelection(text: text) //text is the value select from UILAbel o the option the user select
    self.dismiss(animated: true, completion: nil)
}

然后 firstViewController 中的内容符合此类的applySelection协议

class FirstViewController: UIViewController,applySelection{
func applyText(text: String){
   //update the UIlabel here 

2-使用闭包。 在 secondViewController 中,您应该添加一个这样的新变量,

 var applyText: ((String) -> Void)?

然后

@IBAction func saveButtom(sender: UIButton){
    self.applyText(text) //text is your text to update
}

以及 firstViewController 中,以准备像这样的segue重写。

let vc = segue.destination as! fisrtViewController)
            vc.applyText = { [weak self] data in
                guard let self = self else {return}
                self.text = text //this is assigning the text to self-text supposing text is a UILabel in this viewController                    
            }

您可以尝试两种似乎最适合您的方法之一。

编辑

尝试一下。

 class ViewController2: UIViewController {
        var selectionDelegate:gameModeDelegate!

    @IBAction func chooseButton(_ sender: Any) {

        selectionDelegate.didTapChoice(test: "TEST")
        //if segue is a show segue
        self.navigationController?.popViewController(animated: true)
       //else is a modal segue.
        dismiss(animated: true, completion: nil)
    }
    override func viewDidLoad() {
        super.viewDidLoad() 
    }
}

PD。您不必呈现视图堆栈中已经存在的ViewController,只需散布它即可。祝你好运