[ios] iOS 6에서 UIViewController를 세로 방향으로 강제하는 방법

는 다음과 같이 ShouldAutorotateToInterfaceOrientation아이폰 OS 6에서 사용되지 않는 내가 그에게 특정 뷰를 강제로 사용되는 세로 만 , 아이폰 OS 6에서이 작업을 수행하는 올바른 방법은 무엇입니까? 이것은 내 앱의 한 영역에만 해당되며 다른 모든보기는 회전 할 수 있습니다.



답변

모든 내비게이션 컨트롤러가 상위 뷰 컨트롤러를 존중하도록하려면 카테고리를 사용하여 여러 클래스 이름을 살펴보고 변경할 필요가 없습니다.

@implementation UINavigationController (Rotation_IOS6)

-(BOOL)shouldAutorotate
{
    return [[self.viewControllers lastObject] shouldAutorotate];
}

-(NSUInteger)supportedInterfaceOrientations
{
    return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}

@end

일부 의견에서 지적했듯이 이것은 문제에 대한 빠른 수정입니다. 더 나은 솔루션은 UINavigationController 하위 클래스이며 이러한 메서드를 거기에 배치하는 것입니다. 하위 클래스는 6과 7을 지원하는데도 도움이됩니다.


답변

iOS6를위한 가장 좋은 방법은 Ray Wenderlich 팀의 “iOS6 By Tutorials”( http://www.raywenderlich.com/ )에 명시되어 있으며 UINavigationController대부분의 경우 서브 클래 싱보다 낫습니다 .

UINavigationController초기 뷰 컨트롤러로 세트 가 포함 된 스토리 보드와 함께 iOS6를 사용하고 있습니다 .

//AppDelegate.m-불행히도 iOS6 이전에는이 ​​메서드를 사용할 수 없습니다.

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
NSUInteger orientations = UIInterfaceOrientationMaskAllButUpsideDown;

if(self.window.rootViewController){
    UIViewController *presentedViewController = [[(UINavigationController *)self.window.rootViewController viewControllers] lastObject];
    orientations = [presentedViewController supportedInterfaceOrientations];
}

return orientations;
}

//MyViewController.m-각각에 대해 지원하려는 방향을 반환합니다. UIViewController

- (NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskPortrait;
}


답변

이 답변은 OP 게시물의 의견에서 묻는 질문과 관련이 있습니다.

뷰가 주어진 방향으로 나타나도록 강제하려면 viewWillAppear에 다음을 넣으십시오.

UIApplication* application = [UIApplication sharedApplication];
if (application.statusBarOrientation != UIInterfaceOrientationPortrait)
{
    UIViewController *c = [[UIViewController alloc]init];
    [self presentModalViewController:c animated:NO];
    [self dismissModalViewControllerAnimated:NO];
}

약간의 해킹이지만 UIViewController이전 컨트롤러가 가로 모드 인 경우에도 세로로 표시되도록 강제합니다.

iOS7 업데이트

위의 방법은 이제 더 이상 사용되지 않으므로 iOS 7의 경우 다음을 사용하십시오.

UIApplication* application = [UIApplication sharedApplication];
if (application.statusBarOrientation != UIInterfaceOrientationPortrait)
{
     UIViewController *c = [[UIViewController alloc]init];
     [c.view setBackgroundColor:[UIColor redColor]];
     [self.navigationController presentViewController:c animated:NO completion:^{
            [self.navigationController dismissViewControllerAnimated:YES completion:^{
            }];
     }];
}

흥미롭게도, 기록의 시간에 하나 , 본 해제 또는 애니메이션되어야한다. 둘 다 그렇지 않으면 흰색 화면이 나타납니다. 이것이 왜 작동하는지 모르겠지만 작동합니다! 시각적 효과는 애니메이션에 따라 다릅니다.


답변

그래서 세로 모드 만 표시 할 때 동일한 문제가 발생했습니다. 일반적으로, 나는를 만들 것 UINavigationController, 설정된 viewController는 AS를 rootViewController다음을 표시 UINavigationController모달보기로. 그러나 iOS 6에서는 viewController이제 navigationController에 지원되는 인터페이스 방향 (기본적으로 모두 iPad 용이고 iPhone 용은 거꾸로되어 있음)을 묻습니다.

솔루션 : UINavigationController자동 회전 메서드 를 하위 클래스로 만들고 재정의해야했습니다. 일종의 절름발이.

- (BOOL)shouldAutorotate {
    return NO;
}

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskPortrait;
}
// pre-iOS 6 support 
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
    return (toInterfaceOrientation == UIInterfaceOrientationPortrait);
}


답변

IOS 5

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{

    return (interfaceOrientation == UIInterfaceOrientationPortrait);

}

IOS 6

-(BOOL)shouldAutorotate{
    return YES;
}

-(NSInteger)supportedInterfaceOrientations{

    //    UIInterfaceOrientationMaskLandscape;
    //    24
    //
    //    UIInterfaceOrientationMaskLandscapeLeft;
    //    16
    //
    //    UIInterfaceOrientationMaskLandscapeRight;
    //    8
    //
    //    UIInterfaceOrientationMaskPortrait;
    //    2

    //    return UIInterfaceOrientationMaskPortrait; 
    //    or
          return 2;
}


답변

UIViewController 회전 메서드가 범주 자체에서 선언되어 다른 범주에서 재정의하면 정의되지 않은 동작이 발생하기 때문에 @aprato 대답에 동의하지 않습니다. UINavigationController (또는 UITabBarController) 하위 클래스에서 재정의하는 것이 더 안전합니다.

또한 이것은 가로보기에서 세로 전용 VC로 또는 그 반대로 푸시 / 프레젠테이션 / 팝 시나리오를 다루지 않습니다. 이 어려운 문제를 해결하려면 (Apple에서 해결하지 않음) 다음을 수행해야합니다.

iOS <= 4 및 iOS> = 6 :

UIViewController *vc = [[UIViewController alloc]init];
[self presentModalViewController:vc animated:NO];
[self dismissModalViewControllerAnimated:NO];
[vc release];

iOS 5에서 :

UIWindow *window = [[UIApplication sharedApplication] keyWindow];
UIView *view = [window.subviews objectAtIndex:0];
[view removeFromSuperview];
[window addSubview:view];

이것들은 UIKit이 모든 shouldAutorotate, supportedInterfaceOrientations 등을 재평가하도록 강제합니다.


답변

https://stackoverflow.com/a/13982508/2516436https://stackoverflow.com/a/17578272/2516436을 혼합하는 매우 좋은 접근 방식이 있습니다.

-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
    NSUInteger orientations = UIInterfaceOrientationMaskAllButUpsideDown;


    if(self.window.rootViewController){
        UIViewController *presentedViewController = [self topViewControllerWithRootViewController:self.window.rootViewController];
        orientations = [presentedViewController supportedInterfaceOrientations];
    }

    return orientations;
}

- (UIViewController*)topViewControllerWithRootViewController:(UIViewController*)rootViewController {
    if ([rootViewController isKindOfClass:[UITabBarController class]]) {
        UITabBarController* tabBarController = (UITabBarController*)rootViewController;
        return [self topViewControllerWithRootViewController:tabBarController.selectedViewController];
    } else if ([rootViewController isKindOfClass:[UINavigationController class]]) {
        UINavigationController* navigationController = (UINavigationController*)rootViewController;
        return [self topViewControllerWithRootViewController:navigationController.visibleViewController];
    } else if (rootViewController.presentedViewController) {
        UIViewController* presentedViewController = rootViewController.presentedViewController;
        return [self topViewControllerWithRootViewController:presentedViewController];
    } else {
        return rootViewController;
    }
}

각 UIViewController에 대해 지원하려는 방향을 반환합니다.

- (NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskPortrait;
}