Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MPVolumeView route list is supporting all orientations and ignoring underlying view controller

This appears to be an OS bug, but a workaround is still needed.

Targeting iOS 8 or 9, using view controller based orientation, MPVolumeView's route list will always rotate, even if its parent view controller only supports a single orientation.

This can cause the system to get into an incorrect orientation state where the view controller is shown in portrait, but the status bar (and control center) are landscape.

Have created a test project that demonstrates the bug: https://github.com/NextFaze/MPVolumeViewTest

like image 418
Ric Santos Avatar asked Nov 08 '22 23:11

Ric Santos


1 Answers

hacky solution using swizzling:

#import "UIViewController+RoutingSheet.h"
#import <objc/runtime.h>

@implementation UIViewController (RoutingSheet)

+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        SEL originalSelector = @selector(shouldAutorotate);
        SEL swizzledSelector = @selector(shouldAutoRotateOverrideRoutingSheet);
        Method originalMethod = class_getInstanceMethod(self, originalSelector);
        Method extendedMethod = class_getInstanceMethod(self, swizzledSelector);
        method_exchangeImplementations(originalMethod, extendedMethod);
    });
}

- (UIWindow *)currentWindow {
    for (UIWindow *window in [[UIApplication sharedApplication] windows]) {
        if (window.rootViewController == self)
            return window;
    }
    return nil;
}

- (BOOL)shouldAutoRotateOverrideRoutingSheet {
    UIWindow *window = [self currentWindow];
    if (window != nil) {
        NSString *className = NSStringFromClass(window.class);
        if ([className containsString:@"MPAVRoutingSheetSecureWindow"]) {
            return NO;
        }
    }
    return [self shouldAutoRotateOverrideRoutingSheet];
}

@end
like image 166
Andrew Avatar answered Nov 14 '22 23:11

Andrew