Can I rotate a UIView without the black bars?

后端 未结 4 1505
后悔当初
后悔当初 2020-12-11 09:51

I have a UIView that takes up the entirety of the window on the iphone. When it rotates to landscape, the edges get the little black bars until it snaps into place, as i wou

相关标签:
4条回答
  • 2020-12-11 10:05

    You need to do two things to make this happen.

    First, the window's root view controller will always resize its view to the size of the window. So your big view needs to be a subview of the root view controller's view (to keep it from being resized down), and your root view controller's view needs to have clipsToBounds set to NO. In fact all ancestors of the big view need to have clipsToBounds set to NO.

    Second, when the window rotates, it gives itself black subviews to explicitly hide any views that would otherwise appear outside the window's bounds. It places these black subviews in front of its root view controller's view. You need to move your root view controller's view to the front, like this:

    - (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
        UIWindow *window = self.view.window;
        [window bringSubviewToFront:window.rootViewController.view];
    }
    
    0 讨论(0)
  • 2020-12-11 10:12

    I'm currently working on an app that requires the screen to rotate at a slower than standard speed. In order to stop the black rotation rectangle clipping the view (at the standard rotation speed) before my own rotation began I simply checked the box next to General -> Deployment Info -> Requires Full Screen.

    I do also have the status bar hidden on the view controller although the hide status bar box isn't checked.

    0 讨论(0)
  • 2020-12-11 10:13

    UINavigationController and UITabBarController both have system subviews (UINavigationController: UINavigationTransitionView; UITabBarController: UITransitionView and UIViewControllerWrapperView) that have layer.masksToBounds set to YES by default. In order to eliminate the black edges during rotation, you must set these and all other hierarchical view's layer.masksToBounds to NO.

    However, I'm not sure what the effect of altering the above-mentioned system views' layers is, so I recommend resetting their layer.masksToBounds back to YES once you are done animating.

    0 讨论(0)
  • 2020-12-11 10:26

    I found an alternate way that works when you have two UIWindows overlapping. (This might be the case if you want non-rotatable content in the background, with a rotatable interface floating on top.) The idea is to directly search for the black bar subviews in the frontmost UIWindow when willAnimateRotationToInterfaceOrientation is called, and explicitly hide them. The following code searches two levels deep:

    -(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration {
        UIWindow* window = self.view.window;
        for (UIView* view in [window subviews]) {
            if (!CGRectIntersectsRect(window.bounds, view.frame)) {
                view.hidden = YES;
            }
    
            for (UIView* view_ in [view subviews]) {
                CGRect frame = [view_ convertRect:view_.frame toView:window];
                if (!CGRectIntersectsRect(window.bounds, frame)) {
                    view_.hidden = YES;
                }
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题