如何确定当前视图控制器是否处于活动状态,如果处于活动状态则执行代码
How to determine whether current view controller is active, and execute code if active
在我的应用程序中,有一个 ViewController.swift 文件和一个弹出 ViewController.swift 文件。在应用程序内部,当我打开 popupViewController 并使用故事板 segue 作为 presentModally,然后使用代码 dismiss()
从 popupViewController 返回到 ViewController 时,方法 viewDidLoad, viewWillAppear, viewDidAppear, ViewWillLayoutSubviews
等什么都没有用,它们只执行一次并且在我去 return 回来时不重复。所以,我想在每次 viewController.swift 处于活动状态时执行代码。我在 Whosebug 中找不到关于此的有用信息。
同时,我对通知和观察者了解不多(如果确实需要的话),因此,您能否在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
}
}
正如我在评论中提到的,我不使用故事板。可能有一种方法可以创建 unwind segue - 也可能不会 - 但 [这里有一个 link][1] 可以帮助您使用仅故事板的方式来解决您的问题。快速搜索“模态”找到 9 个匹配项,第二个开始详细介绍。
我认为问题在于什么是模态。基本上,正确执行 viewDidAppear
的第一个视图控制器 仍然 可见。因此,当您的第二个 VC 出现时,它实际上没有执行 viewDidDisappear
。
您可能想稍微改变一下您的概念 - 一个应用程序 window(想想 AppDelegate
and/or SceneDelegate
变成 active,其中 UIViewController
有一个 initialized 和 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)
}
这不会发送任何数据,只会发送模态框消失的事实。如果你想发送数据——比如说,一个字符串或一个 table 单元格值,将 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() 的任何引用。尝试将视图(和视图控制器)视为 appearing/disappearing,而不是 background/foreground。
- 虽然第一个视图在背景中可见,但它仍然可见。所以诀窍是针对模态视图的消失进行编码。
在我的应用程序中,有一个 ViewController.swift 文件和一个弹出 ViewController.swift 文件。在应用程序内部,当我打开 popupViewController 并使用故事板 segue 作为 presentModally,然后使用代码 dismiss()
从 popupViewController 返回到 ViewController 时,方法 viewDidLoad, viewWillAppear, viewDidAppear, ViewWillLayoutSubviews
等什么都没有用,它们只执行一次并且在我去 return 回来时不重复。所以,我想在每次 viewController.swift 处于活动状态时执行代码。我在 Whosebug 中找不到关于此的有用信息。
同时,我对通知和观察者了解不多(如果确实需要的话),因此,您能否在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
}
}
正如我在评论中提到的,我不使用故事板。可能有一种方法可以创建 unwind segue - 也可能不会 - 但 [这里有一个 link][1] 可以帮助您使用仅故事板的方式来解决您的问题。快速搜索“模态”找到 9 个匹配项,第二个开始详细介绍。
我认为问题在于什么是模态。基本上,正确执行 viewDidAppear
的第一个视图控制器 仍然 可见。因此,当您的第二个 VC 出现时,它实际上没有执行 viewDidDisappear
。
您可能想稍微改变一下您的概念 - 一个应用程序 window(想想 AppDelegate
and/or SceneDelegate
变成 active,其中 UIViewController
有一个 initialized 和 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)
}
这不会发送任何数据,只会发送模态框消失的事实。如果你想发送数据——比如说,一个字符串或一个 table 单元格值,将 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() 的任何引用。尝试将视图(和视图控制器)视为 appearing/disappearing,而不是 background/foreground。- 虽然第一个视图在背景中可见,但它仍然可见。所以诀窍是针对模态视图的消失进行编码。