首页 > 解决方案 > 如何确定当前视图控制器是否处于活动状态,如果处于活动状态则执行代码

问题描述

在我的应用程序中,有一个 ViewController.swift 文件和一个 popupViewController.swift 文件。在应用程序内部,当我使用 storyboard segue 作为 presentModally 打开 popupViewController 然后使用代码从 popupViewController 返回到 ViewController 时dismiss(),方法viewDidLoad, viewWillAppear, viewDidAppear, ViewWillLayoutSubviews等没有任何作用,它们只执行一次,并且在我返回时不会重复。所以,我想在每次 viewController.swift 处于活动状态时执行代码。我在 stackoverflow 中找不到关于此的有用信息。

同时,我对通知和观察者不太了解(如果确实需要的话),因此,您能否详细说明如何在 Swift 中(而不是 Objective-c)中做到这一点?我的意思是如何确定当前视图控制器是否处于活动状态。

编辑:我正在从 StoryBoard segue,presentModally 导航。故事板中没有导航控制器。

我尝试了一些代码,但没有任何反应。我到目前为止的重点是:

override func viewDidLoad() {
        super.viewDidLoad()
    NotificationCenter.default.addObserver(self, selector:#selector(appWillEnterForeground), name:UIApplication.willEnterForegroundNotification, object: nil) 
}

@objc func appWillEnterForeground() {
        print("asdad") //nothing happens
        if self.viewIfLoaded?.window != nil {
            // viewController is visible
            print("CURRENT VİEW CONTROLLER") //nothing happens
        }
    }

标签: swiftviewcontroller

解决方案


正如我在评论中提到的,我不使用故事板。可能有一种方法可以创建一个放松的转场 - 或者可能没有 - 但是 [这里有一个链接][1] 可以帮助您使用仅故事板的方式来解决您的问题。快速搜索“modal”找到了 9 个点击,第二个开始详细介绍。

我认为问题在于模式是什么。基本上,您的第一个正确执行的视图控制器viewDidAppear仍然可见。因此,viewDidDisappear当您的第二个 VC 出现时,它实际上并没有执行。

您可能想稍微改变一下您的概念 - 一个应用程序窗口(想想AppDelegate和/或SceneDelegate变得活跃,其中 aUIViewController初始化取消UIView初始化,以及已加载的根,出现*和消失*。这很重要,因为什么您要做的是从模态 VC 的viewDidDisappear覆盖发送您的通知。

首先,我发现将所有通知定义放在扩展中是最容易的:

extension Notification.Name {
    static let modalHasDisappeared = Notification.Name("ModalHasDisappeared")
}

这不仅有助于减少字符串拼写错误,还可以让 Xcode 的代码完成功能发挥作用。

接下来,在您的第一个视图控制器中,向此通知添加一个观察者:

init() {
    super.init(nibName: nil, bundle: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(modalHasDisappeared), name: .modalHasDisappeared, object: nil)
}
required init?(coder: NSCoder) {
    super.init(coder: coder)
    NotificationCenter.default.addObserver(self, selector: #selector(modalHasDisappeared), name: .modalHasDisappeared, object: nil)
}
@objc func modalHasDisappeared() {
    print("modal has disappeared")
}

为了清楚起见,我添加了两种形式init。由于您使用的是故事板,我希望这init(coder:)是您需要的。

最后,当模态消失时发送通知:

override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)
    NotificationCenter.default.post(name: .modalHasDisappeared, object: nil, userInfo: nil)
}

这不会发送任何数据,只是模式已经消失的事实。如果要发送数据 - 例如字符串或表格单元格值,请将object参数更改为:

NotificationCenter.default.post(name: .modalHasDisappeared, object: myLabel, userInfo: nil)

并在您的第一个 VC 中进行以下更改:

NotificationCenter.default.addObserver(self, selector: #selector(modalHasDisappeared(_:)), name: .modalHasDisappeared, object: nil)

@objc func modalHasDisappeared(_ notification:Notification) {
    let label = notification.object as! UILabel!
    print(label.text)
}

最后的笔记:

  • 重复一遍,请注意,通过声明对 的扩展Notification.Name,我只有一个地方声明了一个字符串。
  • AppDelegateor中没有代码SceneDelegate,也没有对 `UIApplication() 的任何引用。尝试将视图(和视图控制器)视为出现/消失,而不是背景/前景。
  • 虽然第一个视图在视觉上位于背景中,但它仍然可见。因此,诀窍是针对模态视图进行编码而不是消失。

推荐阅读