当模态视图被解除时,VC中的触发功能

时间:2021-11-29 11:08:00

I’m trying to trigger a function after dismissing a modal VC (FirstStartVC) back to the main VC. I know that I have to use delegation but it doesn’t work and my debug area stays empty.

我正在尝试在将模态VC(FirstStartVC)解除回主VC后触发一个函数。我知道我必须使用委托,但它不起作用,我的调试区域保持空白。

In other question topics there were people who had it work exact the same way like below. So I have no idea what I’m doing wrong. Does anyone know what I need to change to the code?

在其他问题主题中,有人将其工作方式与下面完全相同。所以我不知道我做错了什么。有谁知道我需要更改代码?

//  FirstStartVC.swift
//

import UIKit
import CoreData
import JSSAlertView

protocol NewUser: class {
    func newUserAction()
}

class FirstStartVC: UITableViewController, UITextFieldDelegate {

    var delegation : NewUser?

    func saveNewUser(){
            self.delegation?.newUserAction()
            self.dismiss(animated: true, completion: nil)
        }
    }

    @IBAction func saveSettings(_ sender: Any) {
        self.saveNewUser()
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        print (delegation)

    }
}





//
//  ViewController.swift
//

import UIKit
import UserNotifications
import GoogleMobileAds
import CoreData
import JSSAlertView

class ViewController: UIViewController, UNUserNotificationCenterDelegate, NewUser {
    func newUserAction() {
        print("Reload some labels")
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        var firstStart = FirstStartVC()
        firstStart.delegation = self

    }
}

3 个解决方案

#1


7  

Swift 3

斯威夫特3

In your main VC viewDidLoad add:

在你的主VC viewDidLoad中添加:

NotificationCenter.default.addObserver(self, selector: #selector(mainVc.functionName), name:"NotificationID", object: nil)

and add a function in main VC

并在主VC中添加一个功能

func functionName() {

    // Do stuff

}

in FirstStartVC call the method with

在FirstStartVC中调用方法

NotificationCenter.default.postNotificationName("NotificationID", object: nil)

Hope this helps!

希望这可以帮助!

#2


2  

In your code, you have:

在您的代码中,您有:

func saveNewUser(){
        self.delegation?.newUserAction()
        self.dismiss(animated: true, completion: nil)
    }
}

Simply write the code you want to run after dismissing in completion::

只需在完成解雇后编写您想要运行的代码::

func saveNewUser() {
        self.delegation?.newUserAction()
        self.dismiss(animated: true, completion: { finished in
            // on completion
        })
    }
}

(You might not even need to say finished in or anything like that.)

(你甚至可能不需要说完或类似的东西。)

#3


0  

If the code you need to execute within newUserAction() is a part of FirstStartVC, you should just call it inside the completion handler of the dismiss(_:animated:) method. However, if you need the code to execute on the VC that presented FirstStartVC, make sure that it conforms to the NewUser protocol. You could do something like this (assuming the presenting VC was named something like PresentingViewController - change it to whatever is the case for your project):

如果你需要在newUserAction()中执行的代码是FirstStartVC的一部分,你应该在dismiss(_:animated :)方法的完成处理程序中调用它。但是,如果您需要在提供FirstStartVC的VC上执行代码,请确保它符合NewUser协议。你可以这样做(假设呈现的VC被命名为类似于PresentingViewController - 将其更改为你的项目的情况):

class PresentingViewController: UIViewController {

    // However you instantiate the FirstStartVC
    let firstStart = FirstStartVC()

    // set the delegation property to self
    firstStart.delegation = self

}

Then at the bottom of the screen create an extension so it conforms to the protocol:

然后在屏幕的底部创建一个扩展,以便它符合协议:

extension PresentingViewController: NewUser {

    func newUserAction() {

        // Here you can do whatever you want when the delegation calls this method

    }

}

EDIT: - Further recommendation...

编辑: - 进一步的建议......

I always find it best practice with delegates to use a weak reference to prevent memory problems. To do so you have to make sure to set the protocol as :class, which you've already completed: protocol NewUser: class. So then when you create the property at the top of FirstStartVC you would just say

我总是发现代表们最好的做法是使用弱引用来防止内存问题。为此,您必须确保将协议设置为:class,您已经完成了:protocol NewUser:class。那么当您在FirstStartVC顶部创建属性时,您只需说

weak var delegation: NewUser?

Your code will still run the same, I just recommend doing it this way as it's helped me avoid memory issues in numerous instances.

你的代码仍然会运行相同,我只是建议这样做,因为它帮助我在许多情况下避免内存问题。

#1


7  

Swift 3

斯威夫特3

In your main VC viewDidLoad add:

在你的主VC viewDidLoad中添加:

NotificationCenter.default.addObserver(self, selector: #selector(mainVc.functionName), name:"NotificationID", object: nil)

and add a function in main VC

并在主VC中添加一个功能

func functionName() {

    // Do stuff

}

in FirstStartVC call the method with

在FirstStartVC中调用方法

NotificationCenter.default.postNotificationName("NotificationID", object: nil)

Hope this helps!

希望这可以帮助!

#2


2  

In your code, you have:

在您的代码中,您有:

func saveNewUser(){
        self.delegation?.newUserAction()
        self.dismiss(animated: true, completion: nil)
    }
}

Simply write the code you want to run after dismissing in completion::

只需在完成解雇后编写您想要运行的代码::

func saveNewUser() {
        self.delegation?.newUserAction()
        self.dismiss(animated: true, completion: { finished in
            // on completion
        })
    }
}

(You might not even need to say finished in or anything like that.)

(你甚至可能不需要说完或类似的东西。)

#3


0  

If the code you need to execute within newUserAction() is a part of FirstStartVC, you should just call it inside the completion handler of the dismiss(_:animated:) method. However, if you need the code to execute on the VC that presented FirstStartVC, make sure that it conforms to the NewUser protocol. You could do something like this (assuming the presenting VC was named something like PresentingViewController - change it to whatever is the case for your project):

如果你需要在newUserAction()中执行的代码是FirstStartVC的一部分,你应该在dismiss(_:animated :)方法的完成处理程序中调用它。但是,如果您需要在提供FirstStartVC的VC上执行代码,请确保它符合NewUser协议。你可以这样做(假设呈现的VC被命名为类似于PresentingViewController - 将其更改为你的项目的情况):

class PresentingViewController: UIViewController {

    // However you instantiate the FirstStartVC
    let firstStart = FirstStartVC()

    // set the delegation property to self
    firstStart.delegation = self

}

Then at the bottom of the screen create an extension so it conforms to the protocol:

然后在屏幕的底部创建一个扩展,以便它符合协议:

extension PresentingViewController: NewUser {

    func newUserAction() {

        // Here you can do whatever you want when the delegation calls this method

    }

}

EDIT: - Further recommendation...

编辑: - 进一步的建议......

I always find it best practice with delegates to use a weak reference to prevent memory problems. To do so you have to make sure to set the protocol as :class, which you've already completed: protocol NewUser: class. So then when you create the property at the top of FirstStartVC you would just say

我总是发现代表们最好的做法是使用弱引用来防止内存问题。为此,您必须确保将协议设置为:class,您已经完成了:protocol NewUser:class。那么当您在FirstStartVC顶部创建属性时,您只需说

weak var delegation: NewUser?

Your code will still run the same, I just recommend doing it this way as it's helped me avoid memory issues in numerous instances.

你的代码仍然会运行相同,我只是建议这样做,因为它帮助我在许多情况下避免内存问题。