12

で何かをする必要がありますapplicationDidEnterBackground。ただし、「バックグラウンドに入る」原因となるユーザー アクション (画面ロックまたはホーム ボタンの押下) を区別する必要があります。

この投稿からのこのコードを使用していました-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、ユーザーがホーム ボタンまたはロック ボタンをクリックしても、常に が表示されます。

誰かがこれを引き起こす原因について考えを持っていますか? マルチタスクのバックグラウンド処理に対する iOS 7 の更新? または、アプリの設定 (アプリのバックグラウンド モードがオフになっている) ですか?

また、代替ソリューションはありますか?

4

3 に答える 3

19

これは、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");
    }
}

于 2013-11-04T15:56:01.530 に答える
0

Swift では動作しません。Swift で動作させるには、次のように変更する必要があります。

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

ヘッドも作成します: #import

@interface LockNotifierCallback : NSObject


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


@end

2.このファイルを迅速にブリッジします

3.APPdelegate.swift に関数を追加します。

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

PS:UIApplicationState はここでは完全には機能しません

于 2015-03-06T16:04:04.510 に答える