如何将值从 SceneDelegate 文件传输到 ViewController (Swift 5)

Posted

技术标签:

【中文标题】如何将值从 SceneDelegate 文件传输到 ViewController (Swift 5)【英文标题】:How to transfer a value from a SceneDelegate file to a ViewController (Swift 5) 【发布时间】:2020-08-18 14:20:42 【问题描述】:

在其中一个 SceneDelegate 方法中,我想为另一个 ViewController 中的变量赋值。我怎样才能做到这一点?总是为零。我尝试了不同的方法,但由于某种原因它们不起作用,我想使用完成处理程序,但似乎我无法在 SceneDelegate 方法中做到这一点

class SceneDelegate: UIResponder, UIWindowSceneDelegate 
        
var viewController: ViewController?
   ...
   //This method works when I click on a cell
   func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) 
   if let url = URLContexts.first?.url 

      let oauthCompletion: DropboxOAuthCompletion = 
      if let authResult = $0 
      switch authResult 
      case .success:
         self.dropboxManager.fetchFiles()
         UserDefaults.standard.set(true, forKey:"userAuthorizedInDropbox")
    
         //I want to assign a value here
         self.viewController?.someString = "Some Text"
    
         print("Success! User is logged into Dropbox.")
      case .cancel:
          print("Authorization flow was manually canceled by user!")
      case .error(_, let description):
          print("Error: \(String(describing: description))")
          
      
   
   DropboxClientsManager.handleRedirectURL(url, completion: oauthCompletion)
  
 

...
class ViewController: UIViewController 
   ...
   //But it's still nil
   var someString: String?
   ...
   func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
   dropboxManager.openDropboxAutorization(controller: self)
   


.....
class MainTabBarController: UITabBarController 
let viewController: ViewController = ViewController.loadFromStoryboard()
   override func viewDidLoad() 
        super.viewDidLoad()
    viewControllers = [
            generateVC(rootViewController: viewController, image:           nil, title: "Import")
            ...
        ]

private func generateVC(rootViewController: UIViewController, image: UIImage?, title: String) -> UIViewController 
        let navigationVC = UINavigationController(rootViewController: rootViewController)
        navigationVC.tabBarItem.image = image
        navigationVC.tabBarItem.title = NSLocalizedString(title, comment: "")
        rootViewController.navigationItem.title = NSLocalizedString(title, comment: "")
        return navigationVC
    
   
...

【问题讨论】:

显示分配viewController: ViewController?的时间和地点。 我在标签栏控制器中执行此操作。我在问题中添加了代码 【参考方案1】:

您可以从场景委托中的rootViewController 访问您想要的ViewController。在以下示例中,我正在考虑您所需的视图控制器位于标签栏控制器的第一个标签中。

if let tabbarController = self.window?.rootViewController as? UITabBarController,
   let navigationController = tabbarController.viewControllers?.first as? UINavigationController,
   let desiredController = navigationController.viewControllers.first as? ViewController 
       desiredController.someString = "some value"

但在我看来,这不是推荐的方法,因为可能有很多情况可能取决于应用程序或导航堆栈的状态。

你可以做的是在你想要的ViewController 中添加一个观察者,然后像这样从SceneDelegate 发布通知:

NotificationCenter.default.post(name: Notification.Name(rawValue: "someeventname"), object: "some value")

你可以像这样添加和监听观察者:

import UIKit

class ViewController: UIViewController 

    override func viewDidLoad() 
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        NotificationCenter.default.addObserver(self, selector: #selector(someEventNotificationReceived(notification:)), name: Notification.Name(rawValue: "someeventname"), object: nil)
    
    
    deinit 
        NotificationCenter.default.removeObserver(self, name: Notification.Name(rawValue: "someeventname"), object: nil)
    

    @objc func someEventNotificationReceived(notification: Notification) 
        if let value = notification.object as? String 
            //handle the event here
        
    

【讨论】:

以上是关于如何将值从 SceneDelegate 文件传输到 ViewController (Swift 5)的主要内容,如果未能解决你的问题,请参考以下文章

将值从 bash 反向传输到 LO 宏

使用列表将值从一个类传输到另一个类

C# SQL 命令参数,将值从表单“传输”到对象再到方法

如何将值从ini文件发送到bs4 find? (Python)

通过 Laravel 中的 AJAX 发布请求将值从一个视图传递到另一个视图

如何在反应js中调用或将值从一个js文件传递到另一个文件