2013-10-25 126 views
11

我需要在applicationDidEnterBackground中执行某些操作。但我需要区分哪些用户操作导致“输入背景”:屏幕锁定或主页按钮按下。在iOS7上区分屏幕锁定和主屏幕按钮

我使用这个代码,这是从这个post - How to differentiate between screen lock and home button press on iOS5?

UIApplicationState state = [application applicationState]; 
if (state == UIApplicationStateInactive) { 
    NSLog(@"Sent to background by locking screen"); 
} else if (state == UIApplicationStateBackground) { 
    NSLog(@"Sent to background by home button/switching to other app"); 
} 

它工作正常,在iOS6的。但在iOS7(包括设备和模拟器)上,我总是得到UIApplicationStateBackground,无论用户是单击home还是锁定按钮。

有人有什么可能导致这种情况的想法吗? iOS 7更新到多任务后台处理?或者我的应用程序的某些设置(我的应用程序的背景模式关闭)?

是否有替代解决方案?

+0

可能的重复[如何区分screen loc k和主页按钮在iOS5上按?](http://stackoverflow.com/questions/8303703/how-to-differentiate-between-screen-lock-and-home-button-press-on-ios5) – jmort253

+0

我想我没有说清楚。我在链接上阅读了这篇文章,但这在iOS7中不再适用。我不认为这是重复的。但无论如何,我编辑我的问题来说清楚。 – Perisheroy

+0

好主意澄清,再加上编辑颠倒你的帖子回到顶部,让其他人再次看到它。 :D – jmort253

回答

17

这可以帮助你在iOS6上& iOS7 :)。

当用户按下锁定按钮时,您将收到com.apple.springboard.lockcomplete通知。

//new way 
//put this in - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), 
            NULL, 
            displayStatusChanged, 
            CFSTR("com.apple.springboard.lockcomplete"), 
            NULL, 
            CFNotificationSuspensionBehaviorDeliverImmediately); 

//put this function in AppDelegate 
static void displayStatusChanged(CFNotificationCenterRef center, 
           void *observer, 
           CFStringRef name, 
           const void *object, 
           CFDictionaryRef userInfo) { 
    if (name == CFSTR("com.apple.springboard.lockcomplete")) { 
     [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"kDisplayStatusLocked"]; 
     [[NSUserDefaults standardUserDefaults] synchronize]; 
    } 
} 

//put this in onAppEnterBackground 
UIApplicationState state = [[UIApplication sharedApplication] applicationState]; 
    if (state == UIApplicationStateInactive) { 
     NSLog(@"Sent to background by locking screen"); 
    } else if (state == UIApplicationStateBackground) { 
     if (![[NSUserDefaults standardUserDefaults] boolForKey:@"kDisplayStatusLocked"]) { 
      NSLog(@"Sent to background by home button/switching to other app"); 
     } else { 
      NSLog(@"Sent to background by locking screen"); 
     } 
    } 

//put this in - (void)applicationWillEnterForeground:(UIApplication *)application 
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"kDisplayStatusLocked"]; 
[[NSUserDefaults standardUserDefaults] synchronize]; 

CGFloat screenBrightness = [[UIScreen mainScreen] brightness]; 

NSLog(@"Screen brightness: %f", screenBrightness); 

UIApplicationState state = [[UIApplication sharedApplication] applicationState]; 

if (state == UIApplicationStateInactive) { 

    NSLog(@"Sent to background by locking screen"); 

} else if (state == UIApplicationStateBackground) { 
    if (screenBrightness > 0.0) { 
     NSLog(@"Sent to background by home button/switching to other app"); 
    } else { 
     NSLog(@"Sent to background by locking screen"); 
    } 
} 

+2

如果您发现重复问题,则只要您有15位代表,正确的操作就是将该帖子标记为重复。简单地在网站上发布相同的复制/粘贴答案并不是我们想要的,这会产生噪音。 – jmort253

+0

@ jmort253对不起,我不知道我应该这样做。我是新用户,但我认为我的回答是正确的。 – wqq

+0

不适合我。在iOS 7(模拟器和设备)上测试它。我不认为这是使用[[UIScreen mainScreen]亮度]的正确方法。根据苹果图书馆的文件,这只是在这个应用程序的屏幕亮度设置,而不是当前的屏幕亮度等级。 – Perisheroy

0

它不会在斯威夫特工作,你需要做一些修改,以使其在斯威夫特工作如下

1.创建一个名为LockNotifierCallback.m的objectiveC文件如下:

static void displayStatusChanged(CFNotificationCenterRef center, 
           void *observer, 
           CFStringRef name, 
           const void *object, 
           CFDictionaryRef userInfo) { 
    if ([(__bridge NSString *)name isEqual: @"com.apple.springboard.lockcomplete"]) { 
     NSLog(@"Screen Locked"); 
     [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"kDisplayStatusLocked"]; 
     [[NSUserDefaults standardUserDefaults] synchronize]; 
    } 
} 

@implementation LockNotifierCallback 

+ (void(*)(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo))notifierProc { 
return displayStatusChanged; 
} 

@end 

创建一个头,以及: #进口

@interface LockNotifierCallback : NSObject 


+ (void(*)(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo))notifierProc; 


@end 

2.bridge这个文件,以迅速

3.添加功能APPdelegate.swift:

CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), nil, LockNotifierCallback.notifierProc(), "com.apple.springboard.lockcomplete", nil, CFNotificationSuspensionBehavior.DeliverImmediately) 

PS:UIApplicationState在这里不能正常工作