如何在解除第二个控制器后调用第一个控制器中的函数
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在解除第二个控制器后调用第一个控制器中的函数相关的知识,希望对你有一定的参考价值。
我有两个UIViewController,当我点击一个按钮时,它从第一个视图控制器转到第二个视图控制器。在那之前,我让UIView动画到另一个地方。在关闭第二个View Controller之后,我想将第一个视图控制器中的UIView移回原来的位置。但是,当我从第二个视图控制器调用一个函数在第一个视图控制器中取消第二个视图控制器动画UIview后,它无法获取UIView的属性,并且无法对其进行任何操作。我想因为第一个UIViewController尚未加载。那是问题吗?我该如何解决这个问题?
有两种解决方案可以使用快速闭包
class FirstViewController: UIViewController {
@IBAction func start(_ sender: Any) {
guard let secondController = self.storyboard?.instantiateViewController(withIdentifier: "SecondController") as? SecondController else { return }
secondController.callbackClosure = { [weak self] in
print("Do your stuff")
}
self.navigationController?.pushViewController(secondController, animated: true)
}
}
//----------------------------
class SecondController: UIViewController {
var callbackClosure: ((Void) -> Void)?
override func viewWillDisappear(_ animated: Bool) {
callbackClosure?()
}
}
或者您可以使用协议
class FirstViewController: UIViewController {
@IBAction func start(_ sender: Any) {
guard let secondController = self.storyboard?.instantiateViewController(withIdentifier: "SecondController") as? SecondController else { return }
secondController.delegate = self
self.navigationController?.pushViewController(secondController, animated: true)
}
}
extension ViewController : ViewControllerSecDelegate {
func didBackButtonPressed(){
print("Do your stuff")
}
}
//--------------------------
protocol SecondControllerDelegate : NSObjectProtocol {
func didBackButtonPressed()
}
class SecondController: UIViewController {
weak var delegate: SecondControllerDelegate?
override func viewWillDisappear(_ animated: Bool) {
delegate?.didBackButtonPressed()
}
}
你可以尝试使用一个闭包。像这样的东西:
class FirstViewController: UIViewController {
@IBOutlet weak var nextControllerButton: UIButton!
private let animatableView: UIView = UIView()
private func methodsForSomeAnimation() {
/*
perform some animation with 'animatableView'
*/
}
@IBAction func nextControllerButtonAction() {
// you can choose any other way to initialize controller :)
let storyboard = UIStoryboard(name: "Main", bundle: nil)
guard let secondController = storyboard.instantiateViewController(withIdentifier: "SecondViewController") as? SecondViewController else { return }
secondController.callbackClosure = { [weak self] in
self?.methodsForSomeAnimation()
}
present(secondController, animated: true, completion: nil)
}
}
class SecondViewController: UIViewController {
@IBOutlet weak var dismissButton: UIButton!
var callbackClosure: ((Void) -> Void)?
@IBAction func dismissButtonAction() {
callbackClosure?()
dismiss(animated: true, completion: nil)
/*
or you call 'callbackClosure' in dismiss completion
dismiss(animated: true) { [weak self] in
self?.callbackClosure?()
}
*/
}
}
当您呈现第二个视图控制器时,您可以传递第一个视图控制器的实例。
第二个VC可以保存第一个VC的实例,如下所示:
weak var firstViewController: NameOfController?
那么当你呈现第二个VC时,请确保你设置了值,所以它不是这样的:
firstViewController = self
完成此操作后,您将能够访问该viewControllers函数。
当你说它无法获得UIView的属性时,因为你把它作为私有?为什么在转到第二个ViewController之前,它在第一个控制器消失之前不会替换你的UIView。我认为这是一个必须清理视图控制器状态才能进一步进入第二个视图控制器的情况。
通过Apple文档检查ios生命周期方法:viewWillDisappear或viewDidDisappear,然后使用其中一种方法执行动画。
iOS 11.x Swift 4.0
在调用VC时你放了这个代码......
private struct Constants {
static let ScannerViewController = "Scan VC"
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == Constants.ScannerViewController {
let svc = destination as? ScannerViewController
svc?.firstViewController = self
}
}
你在我的案例“扫描VC”中命名segue的地方,这就是它在Xcode面板中的样子。
现在在扫描VC中,我们在类声明下得到了它
weak var firstViewController: HiddingViewController?
现在稍后在您的代码中,当您准备返回时,我只需在我的firstViewController中设置我关注的变量,就像这样......
self.firstViewController?.globalUUID = code
我在HiddingViewController中设置了这样的...
var globalUUID: String? {
didSet {
startScanning()
}
}
所以基本上当我关闭扫描VC时,我设置了变量globalUUID,它在这里开始扫描方法。
实际上非常简单的解决方案......只需将动画放入viewDidAppear方法即可。每次加载视图时都会调用此方法。
class firstViewController: UIViewController {
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// insert animation here to run when FirstViewController appears...
}
}
以上是关于如何在解除第二个控制器后调用第一个控制器中的函数的主要内容,如果未能解决你的问题,请参考以下文章
堆叠 presentViewController 后 statusBarFrame = 0