2013-10-25 123 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在這裏不能正常工作