如何在没有情节提要的情况下创建 ViewController 并将一个设置为另一个的委托?

Posted

技术标签:

【中文标题】如何在没有情节提要的情况下创建 ViewController 并将一个设置为另一个的委托?【英文标题】:How to create ViewControllers without storyboard and set one as delegate of the other one? 【发布时间】:2017-05-24 13:41:28 【问题描述】:

这是我设置委托的第一个 VC:

class DiscoverVC: UIViewController, SetLocationDelegate 
    var name = ""
    let loc = LocationVC()
     override func viewDidLoad() 
        super.viewDidLoad()
        self.loc.delegate = self
     

      func getLocation(loc: String) 
        self.name = loc
        self.tableView.reloadData()
    
 

这是我通过委托获取数据的第二个视图控制器:

protocol SetLocationDelegate: class 
    func getLocation(loc: String)


class LocationVC: UIViewController 

    weak var delegate: SetLocationDelegate?
    override func viewDidLoad() 
        super.viewDidLoad()
        self.delegate?.getLocation(loc: "Sam")
    

每当我尝试传递数据时,它都不会调用该方法,并且委托也不会被调用。急需帮助。

【问题讨论】:

请检查LocationVC控制器的viewDidLoad()方法是否被调用? 使用代理的strong 引用将适用于您目前weak var delegate: SetLocationDelegate? 是代理的弱引用,将其更改为var delegate: SetLocationDelegate? 它将起作用。 @NishantBhindi 会创建一个导致内存泄漏的保留周期。不要这样做。 LocationVCviewDidLoadLocationVC 中的任何一个都不会被调用,因为 LocationVC() 的实例化(您可以通过在 viewDidLoad 中放置断点轻松检查)或 LocationVCviewDidLoad 之前被调用viewDidLoad of DiscoverVC,即在设置委托之前。 【参考方案1】:

注意:我之前的回答是使用 Storyboard。但是由于提问者不想使用情节提要,所以我在不使用情节提要的情况下替换了我的答案。 [这个答案的灵感来自https://***.com/a/41095757/3549695]

首先,删除 Main.storyboard。然后在项目 -> 部署信息 -> 主界面(选择 LaunchScreen 而不是'Main')

然后在 AppDelegate.swift 上修改 didFinishLaunching 如下:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool 

    window = UIWindow(frame: UIScreen.main.bounds)
    let discoverVC = DiscoverVC() as UIViewController
    let navigationController = UINavigationController(rootViewController: discoverVC)
    navigationController.navigationBar.isTranslucent = false
    self.window?.rootViewController = navigationController
    self.window?.makeKeyAndVisible()

    return true

DiscoverVC.swift 看起来像这样:

import UIKit

class DiscoverVC: UIViewController, SetLocationDelegate 

    var name = ""

    // to instantiate LocationVC once only for testing
    var notVisted = true

    override func viewDidLoad() 
        super.viewDidLoad()

        self.view.backgroundColor = .yellow 
        loadLocationVCOnlyOnce()
    

    func loadLocationVCOnlyOnce() 
        // only visit one
        guard notVisted else  return 

        let locationVC = LocationVC()
        locationVC.delegate = self 
        self.navigationController?.pushViewController(locationVC, animated: true)

    

    func getLocation(loc: String) 
        self.name = loc
        print(name)
    

LocationVC 看起来像这样:

import UIKit

protocol SetLocationDelegate: class 
    func getLocation(loc: String)


class LocationVC: UIViewController 

    weak var delegate: SetLocationDelegate?

    override func viewDidLoad() 
        super.viewDidLoad()

        self.view.backgroundColor = .cyan 
        self.delegate?.getLocation(loc: "Sam")


    


当您启动时,它会自动从 DiscoverVC(黄色背景)移动到 LocationVC(青色背景)。

然后单击顶部的“返回”按钮后,您将在控制台中看到打印的“Sam”。并且您的视图返回到 DiscoverVC(黄色背景)。

【讨论】:

我不使用情节提要。我更喜欢以编程方式做所有事情。那怎么办? 我根据您的要求在没有使用情节提要的情况下更新了上面的答案。如果答案令人满意,请接受并投票。如有其他问题,请发表评论。

以上是关于如何在没有情节提要的情况下创建 ViewController 并将一个设置为另一个的委托?的主要内容,如果未能解决你的问题,请参考以下文章

如何在没有情节提要的情况下实现 Size-Class-Specific Layout?

如何在没有情节提要的情况下使用按钮切换视图?

在没有情节提要的情况下使用 UITableView

如何在没有情节提要的情况下以编程方式实例化视图控制器

在没有任何情节提要参考的情况下在控制器之间传递数据

使用 Swift 在没有情节提要的情况下展开 segue