如何确定当前视图控制器是不是处于活动状态,如果处于活动状态则执行代码
Posted
技术标签:
【中文标题】如何确定当前视图控制器是不是处于活动状态,如果处于活动状态则执行代码【英文标题】:How to determine whether current view controller is active, and execute code if active如何确定当前视图控制器是否处于活动状态,如果处于活动状态则执行代码 【发布时间】:2020-12-12 18:24:23 【问题描述】:在我的应用程序中,有一个 ViewController.swift 文件和一个 popupViewController.swift 文件。在应用程序内部,当我打开带有故事板 segue 为 presentModally 的 popupViewController,然后使用代码 dismiss()
从 popupViewController 返回到 ViewController 时,方法 viewDidLoad, viewWillAppear, viewDidAppear, ViewWillLayoutSubviews
等没有任何作用,它们只执行一次,当我执行时不要重复回去。所以,我想在每次 viewController.swift 处于活动状态时执行代码。我在 *** 中找不到关于此的有用信息。
同时,我对通知和观察者不太了解(如果确实需要的话),因此,您能否逐步详细说明如何在 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
【问题讨论】:
通过UINavigationController
在视图控制器之间来回导航时会调用所有这四个。你是如何向前和向后导航的?你能提供一些代码吗?
@gmdev 我正在从 StoryBoard segue 导航,presentModally。现在更新了添加这一行的帖子
我不使用故事板,但这听起来相当于一个 VC 做另一个的 present
。如果是这样,也许你可以让第一个 VC 成为模态的代表,告诉它它正在被解雇。
我刚刚评论了你的另一个问题。这两个有关系吗? (似乎是。)我并不是要批评。相反,我还有一个问题 - 与我对您的其他问题的问题有些相关。 :-) 如果您只想 (a) 展示一个 VC,然后 (b) 以模态方式展示第二个 VC,为什么 不 用代码而不是故事板来做呢?你对事物有更多的控制权。
@AnthonSanthez 当您以模态方式呈现视图控制器时,您设置的.modalPresentationStyle
是什么?
【参考方案1】:
正如我在 cmets 中提到的,我不使用故事板。可能有一种方法可以创建一个放松的转场 - 或者可能没有 - 但 [这里有一个链接][1] 可以帮助您使用仅故事板的方式来解决您的问题。快速搜索“modal”找到了 9 个点击,第二个开始详细介绍。
我认为问题在于模态是什么。基本上,正确执行viewDidAppear
的第一个视图控制器仍然可见。因此,当您的第二个 VC 出现时,它实际上并没有执行 viewDidDisappear
。
您可能想稍微改变一下您的概念 - 应用程序窗口(想想 AppDelegate
和/或 SceneDelegate
变为活动,其中 UIViewController
有一个 已初始化 和 deinitialized,以及一个 已加载 的根 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
或 SceneDelegate
中没有代码,也没有任何对 `UIApplication() 的引用。尝试将视图(和视图控制器)视为出现/消失,而不是背景/前景。
虽然第一个视图在背景中可视,但它仍然可见。所以诀窍是针对模态视图进行编码而不是消失。
【讨论】:
非常感谢您的详细解释,这是对正在发生的事情的一个很好的总结。我使用不同的转义方法处理了这个问题,所以当我摆脱转义替代方案时,我会尝试你的答案:) 不过,我接受你的回答,因为我感谢你的努力和逐步理解的教学风格。这些信息将帮助其他人像我一样理解底层逻辑,谢谢..以上是关于如何确定当前视图控制器是不是处于活动状态,如果处于活动状态则执行代码的主要内容,如果未能解决你的问题,请参考以下文章
如何确定 Skype 通话当前是不是在 Android 上处于活动状态
确定夏令时 (DST) 在 Java 中是不是在指定日期处于活动状态