Phi*_*ton 270 iphone objective-c viewwillappear ios
我正在编写应用程序,如果用户在通话时查看应用程序,我需要更改视图.
我已经实现了以下方法:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
NSLog(@"viewWillAppear:");
_sv.frame = CGRectMake(0.0, 0.0, 320.0, self.view.bounds.size.height);
}
Run Code Online (Sandbox Code Playgroud)
但是,当应用程序返回到前台时,它不会被调用.
我知道我可以实现:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(statusBarFrameChanged:) name:UIApplicationDidChangeStatusBarFrameNotification object:nil];
Run Code Online (Sandbox Code Playgroud)
但我不想这样做.我宁愿将所有布局信息放在viewWillAppear:方法中,让它处理所有可能的场景.
我甚至试图从applicationWillEnterForeground:调用viewWillAppear:但我似乎无法确定当前哪个是当前的视图控制器.
有人知道处理这个问题的正确方法吗?我确定我错过了一个明显的解决方案.
occ*_*lus 194
该方法viewWillAppear应该在您自己的应用程序中发生的事情的上下文中进行,而不是在您从另一个应用程序切换回应用程序时将应用程序置于前台的上下文中.
换句话说,如果有人查看另一个应用程序或接听电话,然后切换回您之前在后台运行的应用程序,您的UIViewController在您离开应用程序时已经可见"不关心"可以这么说 - 就它而言,它永远不会消失,而且它仍然可见 - 因此viewWillAppear不被称为.
我建议不要打电话给viewWillAppear自己 - 它有一个特定的含义,你不应该颠覆!您可以通过重构来实现相同的效果,如下所示:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self doMyLayoutStuff:self];
}
- (void)doMyLayoutStuff:(id)sender {
// stuff
}
Run Code Online (Sandbox Code Playgroud)
然后你也doMyLayoutStuff从相应的通知中触发:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(doMyLayoutStuff:) name:UIApplicationDidChangeStatusBarFrameNotification object:self];
Run Code Online (Sandbox Code Playgroud)
顺便说一下,没有开箱即用的方法来判断哪个是'当前'的UIViewController.但你可以找到解决方法,例如UINavigationController的委托方法,用于找出何时在其中呈现UIViewController.您可以使用这样的东西来跟踪已经呈现的最新UIViewController.
更新
如果您在各个位上使用适当的自动调整掩码布局UI,有时您甚至不需要处理UI中的"手动"布局 - 它只是处理...
Sur*_*gch 184
简短的回答
使用NotificationCenter观察者而不是viewWillAppear.
override func viewDidLoad() {
super.viewDidLoad()
// set observer for UIApplication.willEnterForegroundNotification
NotificationCenter.default.addObserver(self, selector: #selector(willEnterForeground), name: UIApplication.willEnterForegroundNotification, object: nil)
}
// my selector that was defined above
@objc func willEnterForeground() {
// do stuff
}
Run Code Online (Sandbox Code Playgroud)
答案很长
要了解应用程序何时从后台返回,请使用NotificationCenter观察者而不是viewWillAppear.这是一个示例项目,显示何时发生的事件.(这是对Objective-C答案的改编.)
import UIKit
class ViewController: UIViewController {
// MARK: - Overrides
override func viewDidLoad() {
super.viewDidLoad()
print("view did load")
// add notification observers
NotificationCenter.default.addObserver(self, selector: #selector(didBecomeActive), name: UIApplication.didBecomeActiveNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(willEnterForeground), name: UIApplication.willEnterForegroundNotification, object: nil)
}
override func viewWillAppear(_ animated: Bool) {
print("view will appear")
}
override func viewDidAppear(_ animated: Bool) {
print("view did appear")
}
// MARK: - Notification oberserver methods
@objc func didBecomeActive() {
print("did become active")
}
@objc func willEnterForeground() {
print("will enter foreground")
}
}
Run Code Online (Sandbox Code Playgroud)
首次启动应用程序时,输出顺序为:
view did load
view will appear
did become active
view did appear
Run Code Online (Sandbox Code Playgroud)
按下主页按钮然后将应用程序带回前台后,输出顺序为:
will enter foreground
did become active
Run Code Online (Sandbox Code Playgroud)
因此,如果您最初尝试使用viewWillAppear那么UIApplication.willEnterForegroundNotification可能就是您想要的.
从iOS 9及更高版本开始,您无需删除观察者.该文件规定:
如果您的应用面向iOS 9.0及更高版本或macOS 10.11及更高版本,则无需在其
dealloc方法中取消注册观察者.
小智 138
在viewDidLoad:ViewController 的方法中使用Notification Center 来调用方法,并从那里执行您在viewWillAppear:方法中应该执行的操作.viewWillAppear:直接打电话不是一个好选择.
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(@"view did load");
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationIsActive:)
name:UIApplicationDidBecomeActiveNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationEnteredForeground:)
name:UIApplicationWillEnterForegroundNotification
object:nil];
}
- (void)applicationIsActive:(NSNotification *)notification {
NSLog(@"Application Did Become Active");
}
- (void)applicationEnteredForeground:(NSNotification *)notification {
NSLog(@"Application Entered Foreground");
}
Run Code Online (Sandbox Code Playgroud)
MHC*_*MHC 34
viewWillAppear:animated:,在我看来,iOS SDK中最令人困惑的方法之一,在这种情况下永远不会被调用,即应用程序切换.该方法仅根据视图控制器视图与应用程序窗口之间的关系调用,即,仅当视图的视图出现在应用程序窗口而不是屏幕上时,才会将消息发送到视图控制器.
当您的应用程序进入后台时,显然应用程序窗口的最顶层视图对用户不再可见.但是,在应用程序窗口的视角中,它们仍然是最顶层的视图,因此它们不会从窗口中消失.相反,这些视图消失了,因为应用程序窗口消失了.他们没有消失,因为他们从窗户消失了.
因此,当用户切换回您的应用程序时,它们显然似乎出现在屏幕上,因为窗口再次出现.但从窗口的角度来看,它们根本没有消失.因此视图控制器永远不会收到viewWillAppear:animated消息.
斯威夫特 4.2 / 5
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(willEnterForeground),
name: Notification.Name.UIApplicationWillEnterForeground,
object: nil)
}
@objc func willEnterForeground() {
// do what's needed
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
131324 次 |
| 最近记录: |