iOS视图切换

在公司的业务流程遇到一个问题:

首先规定这个页面是强制竖屏的H5视图控制器页面,当然我们的视线方式是:

1.自定义一个NavigationController,在这个自定义类中定义强制竖屏的方法

2.将这个自定义NavigationController的root视图设置成H5的控制器

3.在keywindow中 present 过去这个被强制竖屏包裹的NavigationController


具体代码如下:

- (void)webviewWithUrl:(NSString *)url viewTag:(NSInteger)tag title:(NSString *)title
{
    CommonWebViewController * commonWebViewController = [[CommonWebViewController alloc] init];

    /* 自定义的一个 */
    RotationViewController * roView = [self webViewOrientationWithController:commonWebViewController]; /* 适应横竖屏 */
    /* 设置强制竖屏标示 */
    roView.viewtag = 6;
    
    /* 获取根窗口 */
    UIWindow *keyWindow = GetKeyWindow;
    [keyWindow.rootViewController presentModalViewController:roView animated:NO];
}

强制竖屏的navigation视图控制器:

@implementation RotationViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
}


#pragma mark - Rotation setting.

- (BOOL)shouldAutorotate
{
    if (self.viewtag == 6) 
    {
        return NO;
    }
    return YES;
}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
    if (self.viewtag == 6) 
    {
        return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
    }
    else
        return UIInterfaceOrientationMaskLandscape;
}

@end


但是,如果!H5界面里面有一个调用摄像头或者相机的功能,这个时候你一旦调用出UIImagePickerViewController,点击就会马上退出界面,并且报以下的问题:

Warning: Attempt to present <UIImagePickerController: 0x150ab800> on <ViewController2: 0x14623580> whose view is not in the window hierarchy!

而这个上传的实现其实也非常简单,只是一个HTML的标签:
<input type="file">


其实这个问题在网上特别多,我分别找了几处:

http://stackoverflow.com/questions/25942676/ios-8-sdk-modal-uiwebview-and-camera-image-picker

https://segmentfault.com/q/1010000004528658

https://segmentfault.com/q/1010000002780277


大概原理就是iOS8的BUG(其实iOS9,iOS10都有这个问题),然后这个视图继承的层级关系是有问题的。

按着他们的想法,我修改了一处就实现了:

- (void)webviewWithUrl:(NSString *)url title:(NSString *)title{
    
    CommonWebViewController * commonWebViewController = [[CommonWebViewController alloc] init];
    
    /* 构建一个临时的控制器 */
    UIViewController* vc = [[UIViewController alloc] init];
    RotationViewController *roView = [[RotationViewController alloc] initWithRootViewController:vc];
    [roView setNavigationBarHidden:YES];
    roView.viewtag = 6;

    UIWindow *keyWindow = GetKeyWindow;
    /* 保存源视图控制器 */
    commonWebViewController.windowRootViewController = keyWindow.rootViewController;

    [keyWindow setRootViewController:roView];
    [roView presentModalViewController:commonWebViewController animated:NO];
}

并且在带有UIWebView的视图控制器添加如上:

-(void)dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion
{
    if ( self.presentedViewController)
    {
        [super dismissViewControllerAnimated:flag completion:completion];
    }
}

原理按照这位大神如下:
The uiwebview causes the uialertcontroller to be presented on the uiwebviewviewcontroller to show the camera/existing/cancel. When user chooses option, then uialertcontroller is meant to be dismissed and the uuiimagepickercontroller presented. However the dismissing of the uialertcontroller seems to fire twice. The first time is ok because the presentedviewcontroller = the uialertcontroller , but the 2nd time the presentedviewcontroller property is nil, and this causes the dismissviewcontrolleranimated method to kill the webviewviewcontroller which is the problem, to I now test for this case


大意就是dismiss的时候强制进行了两次,头一次可以顺利完成,但是第二次这个presentedViewCtonroller是一个nil的属性。这样导致了直接地kill掉最近的那个页面(带webview的界面)

解决方式就是,如果存在需要dismiss的界面才进行dismiss

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值