Created
December 11, 2014 13:25
-
-
Save 0xced/fc0dbc952989fe989c54 to your computer and use it in GitHub Desktop.
Restore MPMoviePlayerController controls autohide behavior after unlocking a device
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * Locking then unlocking a device while a movie is playing disables controls autohiding. | |
| * `MPInlineVideoController` registers for the (private) UIApplicationResumedEventsOnlyNotification | |
| * (which is sent between UIApplicationWillEnterForegroundNotification and UIApplicationDidBecomeActiveNotification). | |
| * In its callback (-[MPInlineVideoController _applicationResumedEventsOnly:]) it calls `[self setDisableControlsAutohide:YES]` | |
| * effectively disabling controls autohide. In order to restore the automatic hiding of controls, we call | |
| * setDisableControlsAutohide:NO when UIApplicationDidBecomeActiveNotification is posted. | |
| */ | |
| #import <MediaPlayer/MediaPlayer.h> | |
| static void EnableControlsAutohide(MPMoviePlayerController *moviePlayerController) | |
| { | |
| NSString *videoViewController = [@[ @"video", @"View", @"Controller" ] componentsJoinedByString:@""]; | |
| NSString *inlineVideoControllerKeyPath = [@[ @"implementation", videoViewController ] componentsJoinedByString:@"."]; | |
| @try | |
| { | |
| id inlineVideoController = [moviePlayerController valueForKeyPath:inlineVideoControllerKeyPath]; | |
| SEL selector = NSSelectorFromString([@[ @"set", @"Disable", @"Controls", @"Autohide", @":" ] componentsJoinedByString:@""]); | |
| NSMethodSignature *methodSignature = [inlineVideoController methodSignatureForSelector:selector]; | |
| if (methodSignature.numberOfArguments != 3) | |
| return; | |
| const char *returnType = methodSignature.methodReturnType; | |
| const char *firstArgType = [methodSignature getArgumentTypeAtIndex:2]; | |
| if (strcmp(returnType, @encode(void)) == 0 && strcmp(firstArgType, @encode(BOOL)) == 0) | |
| { | |
| // Equivalent to [inlineVideoController setDisableControlsAutohide:NO], i.e. enable controls autohide which is the default behavior | |
| NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature]; | |
| [invocation setTarget:inlineVideoController]; | |
| [invocation setSelector:selector]; | |
| BOOL disableControlsAutohide = NO; | |
| [invocation setArgument:&disableControlsAutohide atIndex:2]; | |
| [invocation invoke]; | |
| } | |
| } | |
| @catch (NSException *exception) | |
| { | |
| NSLog(@"%@", exception); | |
| } | |
| } | |
| @implementation NSObject (FixMPMoviePlayerControllerControlsAutohide) | |
| + (void) load | |
| { | |
| static __weak MPMoviePlayerController *currentMoviePlayerController; | |
| dispatch_async(dispatch_get_main_queue(), ^{ | |
| NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter]; | |
| NSOperationQueue *mainQueue = [NSOperationQueue mainQueue]; | |
| [defaultCenter addObserverForName:MPMoviePlayerNowPlayingMovieDidChangeNotification object:nil queue:mainQueue usingBlock:^(NSNotification *notification) { | |
| currentMoviePlayerController = notification.object; | |
| }]; | |
| [defaultCenter addObserverForName:MPMoviePlayerPlaybackDidFinishNotification object:nil queue:mainQueue usingBlock:^(NSNotification *notification) { | |
| currentMoviePlayerController = nil; | |
| }]; | |
| [defaultCenter addObserverForName:UIApplicationDidBecomeActiveNotification object:nil queue:mainQueue usingBlock:^(NSNotification *notification) { | |
| MPMoviePlayerController *moviePlayerController = currentMoviePlayerController; | |
| if (moviePlayerController) | |
| EnableControlsAutohide(moviePlayerController); | |
| }]; | |
| }); | |
| } | |
| @end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment