在进行 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];
}
最终解决了这个问题。
在后期优化调研时发现,上面强制横屏的操作,调用了苹果的私用方法,调用苹果私有方法有审核不过的风险。
网友评论