swift - 如何确定当前视图控制器是否处于活动状态,如果处于活动状态则执行代码
问题描述
在我的应用程序中,有一个 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
}
}
解决方案
正如我在评论中提到的,我不使用故事板。可能有一种方法可以创建一个放松的转场 - 或者可能没有 - 但是 [这里有一个链接][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
,我只有一个地方声明了一个字符串。 AppDelegate
or中没有代码SceneDelegate
,也没有对 `UIApplication() 的任何引用。尝试将视图(和视图控制器)视为出现/消失,而不是背景/前景。- 虽然第一个视图在视觉上位于背景中,但它仍然可见。因此,诀窍是针对模态视图进行编码而不是消失。
推荐阅读
- javascript - 为什么javascript在RN webview中不起作用但桌面浏览器工作正常?
- javascript - 用 JavaScript 创建一个固定列和行的表
- linux - 如何在 docker 实例中找到并杀死不可见的进程?
- python - 在python中获取今天的日期时间
- python - 熊猫用字符串上的条件替换数据框中的值
- slack - 删除#General 频道中所有松弛消息的最简单方法是什么?
- node.js - Fetch 请求不返回数据
- java - 片段未在后退按钮上打开上一个片段
- java - 如何使用 CriteriaUpdate 编写联接?
- r - 具有相同名称但不同的两个匹配列的行平均值:'_1' 和 '_2'