shouldAutorotate not called on view controller

你说的曾经没有我的故事 提交于 2019-12-06 04:42:12

问题


I have a simple app consisting of a single view controller. I started with the Xcode 7 GM Single View Application template, but then deleted the main storyboard, and set up my view controller like this:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

    let vc = ViewController()

    window = UIWindow(frame: UIScreen.mainScreen().bounds)
    window!.rootViewController = vc
    window!.makeKeyAndVisible()

    return true
}

In my info plist, I have all orientations specified under Supported Interface Orientations, and the app rotates to all orientations on iPad.

However, in my simple¹ view controller, the shouldAutorotate() and supportedInterfaceOrientations() methods are never called. This is a problem, because I'm experimenting with a UI control enabling and disabling auto rotation. What could be preventing these methods from being called?

Sample project here (requires Swift 2)


¹non-UINavigationController


回答1:


According to this post on the Apple Developer forum, if you have iPad multitasking enabled (new in iOS 9), you can no longer control the orientations you support:

https://forums.developer.apple.com/message/13508#13508

You can add a counter rotation, but it's not pretty, at least as far as I can tell. I got it working, but was unable to disable the animation of the corners when you rotate so you get this weird looking situation where it looks like it's rotating, but the content doesn't rotate.

Here is the code I was using to counter the rotation. Note that I had to hide the status bar too or it would rotate as well and I couldn't figure out how to counter that.

Also note that doing the auto rotation on self.navigationController.view.superview.superview is likely not the best way and may break at some point in the future. There is likely a better way to get the correct view used to counter the rotation. Obviously if you aren't using a navigation controller, you would need to pass in a different view. YMMV.

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [[UIApplication sharedApplication] setStatusBarHidden:YES];
    self.startingInterfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation];
}

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
    [self updateLayoutsForCurrentOrientation:toInterfaceOrientation view:self.navigationController.view.superview.superview];
}

- (void)updateLayoutsForCurrentOrientation:(UIInterfaceOrientation)toInterfaceOrientation view:(UIView *)view {
    CGAffineTransform transform = CGAffineTransformIdentity;

    if (self.startingInterfaceOrientation == UIInterfaceOrientationPortrait) {
        switch (toInterfaceOrientation) {
            case UIInterfaceOrientationLandscapeLeft:
                transform = CGAffineTransformMakeRotation(M_PI/2.0f);
                break;
            case UIInterfaceOrientationLandscapeRight:
                transform = CGAffineTransformMakeRotation(-M_PI/2.0f);
                break;
            case UIInterfaceOrientationPortrait:
                transform = CGAffineTransformIdentity;
                break;
            case UIInterfaceOrientationPortraitUpsideDown:
                transform = CGAffineTransformMakeRotation(M_PI);
                break;
            default:
                break;
        }
    }
    else if (self.startingInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) {
        switch (toInterfaceOrientation) {
            case UIInterfaceOrientationLandscapeLeft:
                transform = CGAffineTransformMakeRotation(-M_PI/2.0f);
                break;
            case UIInterfaceOrientationLandscapeRight:
                transform = CGAffineTransformMakeRotation(M_PI/2.0f);
                break;
            case UIInterfaceOrientationPortrait:
                transform = CGAffineTransformMakeRotation(M_PI);
                break;
            case UIInterfaceOrientationPortraitUpsideDown:
                transform = CGAffineTransformIdentity;
                break;
            default:
                break;
        }
    }
    else if (self.startingInterfaceOrientation == UIInterfaceOrientationLandscapeLeft) {
        switch (toInterfaceOrientation) {
            case UIInterfaceOrientationLandscapeLeft:
                transform = CGAffineTransformIdentity;
                break;
            case UIInterfaceOrientationLandscapeRight:
                transform = CGAffineTransformMakeRotation(M_PI);
                break;
            case UIInterfaceOrientationPortrait:
                transform = CGAffineTransformMakeRotation(-M_PI/2.0f);
                break;
            case UIInterfaceOrientationPortraitUpsideDown:
                transform = CGAffineTransformMakeRotation(M_PI/2.0f);
                break;
            default:
                break;
        }
    }
    else if (self.startingInterfaceOrientation == UIInterfaceOrientationLandscapeRight) {
        switch (toInterfaceOrientation) {
            case UIInterfaceOrientationLandscapeLeft:
                transform = CGAffineTransformMakeRotation(M_PI);
                break;
            case UIInterfaceOrientationLandscapeRight:
                transform = CGAffineTransformIdentity;
                break;
            case UIInterfaceOrientationPortrait:
                transform = CGAffineTransformMakeRotation(M_PI/2.0f);
                break;
            case UIInterfaceOrientationPortraitUpsideDown:
                transform = CGAffineTransformMakeRotation(-M_PI/2.0f);
                break;
            default:
                break;
        }
    }
    view.transform = transform;
}

Much of this code was adapted from Jared Sinclair's JTSImageViewController (posted with his permission), available under the MIT license on github here: https://github.com/jaredsinclair/JTSImageViewController




回答2:


To opt out of being eligible to participate in Slide Over and Split View, add the UIRequiresFullScreen key to your Xcode project’s Info.plist file and apply the Boolean value YES.




回答3:


I just tried the solution in this thread: https://stackoverflow.com/a/32782517/1679627

Note that there are two entries in the info.plist one for supported orientations on iPhone and one for iPad.



来源:https://stackoverflow.com/questions/32535329/shouldautorotate-not-called-on-view-controller

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!