强制横竖屏

在进行 AR 页面横屏需求的开发的时候,遇到的问题。

AR 页面横屏的需求:

    整个浏览器框架都是竖屏的,但是 VR 页面需要横屏展示双眼模式,因此需要单独处理在 VR 页面的时候将控制器设置为可以横屏的。

开发思路:

    在- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;  方法里,拦截到 URL,然后使用下面这个方法来将URL中的参数解析出来:
- (NSMutableDictionary *)getURLParameters:(NSString *)urlStr {

    // 查找参数

    NSRange range = [urlStr rangeOfString:@"?"];
    if (range.location == NSNotFound) {
        return nil;
    }
    NSMutableDictionary *params = [NSMutableDictionary dictionary];
    NSString *parametersString = [urlStr substringFromIndex:range.location + 1];
    if ([parametersString containsString:@"&"]) {
        NSArray *urlComponents = [parametersString componentsSeparatedByString:@"&"];
        for (NSString *keyValuePair in urlComponents) {
            NSArray *pairComponents = [keyValuePair componentsSeparatedByString:@"="];
            NSString *key = [pairComponents.firstObject stringByRemovingPercentEncoding];
            NSString *value = [pairComponents.lastObject stringByRemovingPercentEncoding];
            if (key == nil || value == nil) {
                continue;
            }
            id existValue = [params valueForKey:key];
            if (existValue != nil) {
                if ([existValue isKindOfClass:[NSArray class]]) {
                    NSMutableArray *items = [NSMutableArray arrayWithArray:existValue];
                    [items addObject:value];
                    [params setValue:items forKey:key];
                } else {
                    [params setValue:@[existValue, value] forKey:key];
                }
            } else {
                [params setValue:value forKey:key];
            }
        }
    } else {
        NSArray *pairComponents = [parametersString componentsSeparatedByString:@"="];
        if (pairComponents.count == 1) {
            return nil;
        }
        NSString *key = [pairComponents.firstObject stringByRemovingPercentEncoding];
        NSString *value = [pairComponents.lastObject stringByRemovingPercentEncoding];
        if (key == nil || value == nil) {
            return nil;
        }
        [params setValue:value forKey:key];
    }
    return params;
}
然后在 - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType; 方法中进行判断:
NSDictionary *paramDic = [self getURLParameters:requestURLString];
    if (paramDic && [paramDic[@"quanjing"] isEqualToString:@"true"]) {
        self.needAutorotate = YES;
    } else {
        self.needAutorotate = NO;
    }

之后重写横屏的两个方法:

- (BOOL)shouldAutorotate {
    return self.needAutorotate;
}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
    if (self.needAutorotate) {
        return UIInterfaceOrientationMaskAllButUpsideDown;
    } else {
        return UIInterfaceOrientationMaskPortrait;
    }
}

以上,基本完成本需求的功能。

但是在自测是发现问题:当在 VR 页面处于横屏状态的时候,点击 VR 页面上的返回按钮,返回到的页面仍然是横屏的,这是不对的,返回到的页面应该是竖屏的。

打断点检查问题:

发现在点击 VR 页面上的返回按钮时,确实走进了self.needAutorotate = NO;

NSDictionary *paramDic = [self getURLParameters:requestURLString];
    if (paramDic && [paramDic[@"quanjing"] isEqualToString:@"true"]) {
        self.needAutorotate = YES;
    } else {
        self.needAutorotate = NO;
    }

于是查找到一个强制横屏的方法:

//强制横竖屏

- (void)interfaceOrientation:(UIInterfaceOrientation)orientation

{

    if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]) {

        SEL selector  = NSSelectorFromString(@"setOrientation:");

        NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[UIDevice instanceMethodSignatureForSelector:selector]];

        [invocation setSelector:selector];

        [invocation setTarget:[UIDevice currentDevice]];

        int val = orientation;

        // 从2开始是因为0 1 两个参数已经被selector和target占用

        [invocation setArgument:&val atIndex:2];
        [invocation invoke];
    }

}

将下面代码改动一下:

NSDictionary *paramDic = [self getURLParameters:requestURLString];
    if (paramDic && [paramDic[@"quanjing"] isEqualToString:@"true"]) {
        self.needAutorotate = YES;
    } else {
        self.needAutorotate = NO;
        [self interfaceOrientation:UIInterfaceOrientationPortrait];
    }

最终解决了这个问题。

在后期优化调研时发现,上面强制横屏的操作,调用了苹果的私用方法,调用苹果私有方法有审核不过的风险。

你可能感兴趣的:(强制横竖屏)