Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/114.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios Xcode Swift委托,新值在VC实例化时被覆盖_Ios_Swift_Xcode - Fatal编程技术网

Ios Xcode Swift委托,新值在VC实例化时被覆盖

Ios Xcode Swift委托,新值在VC实例化时被覆盖,ios,swift,xcode,Ios,Swift,Xcode,我对swift中的授权有一个小问题。我正在尝试将文本从ViewController发送到SecondViewController。当第二个屏幕被加载时,它仍然显示“旧文本”而不是“新文本”。这是我的代码。当视图控制器加载时,“textReceived”变量的值会再次被旧文本覆盖。我不知道为什么下面是我的代码: protocol DataTransferTestProtocol { func receiveTextFromVC1(_ text: String) } class ViewC

我对swift中的授权有一个小问题。我正在尝试将文本从ViewController发送到SecondViewController。当第二个屏幕被加载时,它仍然显示“旧文本”而不是“新文本”。这是我的代码。当视图控制器加载时,“textReceived”变量的值会再次被旧文本覆盖。我不知道为什么下面是我的代码:

protocol DataTransferTestProtocol {
    func receiveTextFromVC1(_ text: String)
}

class ViewController: UIViewController {

    var delegate: DataTransferTestProtocol?

    override func viewDidLoad() {
        super.viewDidLoad()

        let receivingVC = SecondViewController()
        self.delegate = receivingVC
    }

    @IBAction func buttonTapped(_ sender: Any) {
        delegate?.receiveTextFromVC1("NEW TEXT")
    }
}


class SecondViewController: UIViewController, DataTransferTestProtocol {

    @IBOutlet weak var myLabel: UILabel!

    var textReceived = "OLD TEXT"

    func receiveTextFromVC1(_ text: String) {
        textReceived = text
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        myLabel.text = textReceived
    }
}

问题在于这一行:

    let receivingVC = SecondViewController()
您希望与可能在屏幕上看到的第二个ViewController实例对话。但与此相反,您正在制作另一个在屏幕上永远看不到的SecondViewController。因此,发送给代理的更改将永远不可见。(你可能想看看我的文章,)


另一个问题是你是否应该在这里使用委托。委派通常用于从第二个视图控制器通信回第一个视图控制器。向前通信要简单得多:第一个视图控制器了解第二个视图控制器的所有信息,只需直接与之通信。(如果您要解释这些视图控制器是什么以及它们在“全部导入视图控制器”层次结构中如何相互关联,我们可以更具体地说明这一点。)

问题是这一行:

    let receivingVC = SecondViewController()
您希望与可能在屏幕上看到的第二个ViewController实例对话。但与此相反,您正在制作另一个在屏幕上永远看不到的SecondViewController。因此,发送给代理的更改将永远不可见。(你可能想看看我的文章,)


另一个问题是你是否应该在这里使用委托。委派通常用于从第二个视图控制器通信回第一个视图控制器。向前通信要简单得多:第一个视图控制器了解第二个视图控制器的所有信息,只需直接与之通信。(如果您要解释这些视图控制器是什么以及它们在“所有导入视图控制器”层次结构中如何相互关联,我们可以更具体地说明这一点。)

因为您的
视图中有
让receivingVC=SecondViewController()
。当您退出该函数时,您的
receivingVC
实例也将被释放。相反,让您的
作为类的成员接收VC

class ViewController: UIViewController {

    var delegate: DataTransferTestProtocol?

    var receivingVC = SecondViewController() // have your receivingVC here

    override func viewDidLoad() {
        super.viewDidLoad()

        self.delegate = receivingVC
    }

    @IBAction func buttonTapped(_ sender: Any) {
        delegate?.receiveTextFromVC1("NEW TEXT")
    }
}

因为在
viewdiload
中有
let receivingVC=SecondViewController()
。当您退出该函数时,您的
receivingVC
实例也将被释放。相反,让您的
作为类的成员接收VC

class ViewController: UIViewController {

    var delegate: DataTransferTestProtocol?

    var receivingVC = SecondViewController() // have your receivingVC here

    override func viewDidLoad() {
        super.viewDidLoad()

        self.delegate = receivingVC
    }

    @IBAction func buttonTapped(_ sender: Any) {
        delegate?.receiveTextFromVC1("NEW TEXT")
    }
}
非常简单的解决方案:

var receivingVC = SecondViewController()
只需将这一行从
viewDidLoad()
方法中移开即可

然后在这个方法上初始化它,就像这样

class ViewController: UIViewController {
    let receivingVC = SecondViewController()

    var delegate: DataTransferTestProtocol?

override func viewDidLoad() {
    super.viewDidLoad()

    self.delegate = receivingVC
}

@IBAction func buttonTapped(_ sender: Any) {
    delegate?.receiveTextFromVC1("NEW TEXT")
}
}
非常简单的解决方案:

var receivingVC = SecondViewController()
只需将这一行从
viewDidLoad()
方法中移开即可

然后在这个方法上初始化它,就像这样

class ViewController: UIViewController {
    let receivingVC = SecondViewController()

    var delegate: DataTransferTestProtocol?

override func viewDidLoad() {
    super.viewDidLoad()

    self.delegate = receivingVC
}

@IBAction func buttonTapped(_ sender: Any) {
    delegate?.receiveTextFromVC1("NEW TEXT")
}
}

如果要在导航中发送A->B。您应该使用属性not delegate。在您的情况下,如果要在导航中发送A->B,则在将数据发送回上一个控制器A时应该使用delegate。您应该使用属性而不是委派。在您将数据发送回前一个控制器时,委派应该使用。以下是我基于响应的解决方案,必须获得正确的视图控制器:

@IBAction func buttonTapped(_ sender: Any) {

    let storyboard1 = UIStoryboard(name: "Main", bundle: nil)
    let secondVC = storyboard1.instantiateViewController(withIdentifier: "SecondViewController") as! SecondViewController
    self.delegate = secondVC      
    delegate?.receiveTextFromVC1("NEW TEXT")
    self.present(secondVC, animated: true, completion: nil)

}

以下是我基于响应的解决方案,必须获得正确的视图控制器:

@IBAction func buttonTapped(_ sender: Any) {

    let storyboard1 = UIStoryboard(name: "Main", bundle: nil)
    let secondVC = storyboard1.instantiateViewController(withIdentifier: "SecondViewController") as! SecondViewController
    self.delegate = secondVC      
    delegate?.receiveTextFromVC1("NEW TEXT")
    self.present(secondVC, animated: true, completion: nil)

}

您正在将
ViewController
中的委托分配给一个局部变量“receivingVC”,因为当屏幕加载时,会创建一个SecondViewController的新实例。创建的对象与被推送的对象是分开的。如果您的唯一目的只是更新secondView控制器中的文本。不需要使用委托,在secondViewController中声明一个变量,按下secondViewController时,只需将文本分配给它。您在
ViewController
中将委托分配给一个局部变量“receivingVC”,因为当屏幕加载时,会创建secondViewController的一个新实例。创建的对象与他被推了。如果您的唯一目的只是更新secondView控制器中的文本。无需使用委托,在secondViewController中声明一个变量,当按下secondViewController时,只需将文本分配给它。让Storyboard 1=UIStoryboard(名称:“Main”,bundle:nil)让secondVC=Storyboard 1。实例化EWController(标识符:“secondViewController”)为!SecondViewController self.delegate=secondVC仍然是相同的resultNice文章,与情节提要一起使用时必须移动一些代码:'@iAction func buttonTapped(uSender:Any){let Storyboard 1=UIStoryboard(name:“Main”,bundle:nil)let secondVC=Storyboard 1.InstanceDeviceController(标识符为:“SecondViewController”)为!SecondViewController self.delegate=secondVC delegate?.receiveTextFromVC1(“新文本”)self.present(secondVC,动画:true,完成:nil)}'let Storyboard 1=UIStoryboard(名称:“Main”,捆绑:nil)让secondVC=Storyboard 1.InstanceEviewController(标识符为:“SecondViewController”)作为!SecondViewController self.delegate=secondVC仍然是相同的结果,使用故事板时必须移动一些代码:'@iAction func buttonTapped(u发件人:Any){let Storyboard 1=UIStoryboard(名称:“Main”,bundle:nil)让secondVC=storyboard1.实例化eviewcontroller(标识符为“SecondViewController”)为!SecondViewController self.delegate=secondVC delegate?.receiveTextFromVC1(“新文本”)self.present(secondVC,动画:true,完成:nil)}“为什么你认为协议只需要用于