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


85

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

답변:


117

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

@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을 지원하는데도 도움이됩니다.


3
나는 이것이 작동하는지 확인할 수있다. 원하는 경우 "[self.viewControllers lastObject]"를 "self.topViewController"로 바꿀 수도 있습니다.
Wayne Liu

3
이 UINavigationController 범주보다 UITabBarController를 사용하는 경우 도움이되지 않습니다. 당신은 ... 대신 UITabBarController가에 카테고리를해야한다
보 루트 Tomazin

46
이 솔루션의 문제점은 가로 모드에 있던 컨트롤러를 팝하고 새 상단 컨트롤러가 세로 모드 만 지원 (또는 그 반대) 할 때 작동하지 않는다는 것입니다.이 경우 콜백이 호출되지 않으며 방법을 아직 찾지 못했습니다. 새 상단 컨트롤러를 올바른 방향으로 강제합니다. 어떤 아이디어?
Lope

4
UINavigationController를 서브 클래 싱하고 window.rootController로 설정했습니다. 3 가지 방법을 모두 구현했습니다. 장치의 회전을 변경할 때 잘 작동합니다. 문제는 뷰 컨트롤러를 팝업 할 때 해당 방법 (회전과 관련된 것은 없음)이 호출된다는 것입니다.
Lope

4
가로보기 컨트롤러에서 푸시 또는 팝을 수행하는 경우이 강제 UIViewController가 가로로 변경됩니다. 그러나 세로로 회전하면 잘 작동하고 가로로 변경되지 않습니다. 가로에서 밀거나 튀는 유일한 문제. 도와주세요
Tariq 2013 년

63

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;
}

1
이것은 iOS 6을위한 최상의 솔루션입니다
Homam

2
@Phil, iOS 6에서는 잘 작동합니다. 그러나 어떤 경우에는 가로에서 세로로 이동하면 작동하지 않습니다. 왜 그런지 아십니까?
Kirti Nikam 2013 년

1
매우 유용한 솔루션입니다. 저에게는 최고입니다.
오스카 카스텔 론

1
iOS 7 베타 6에서 작업 중입니다. 제 경우에는 가로에서 세로로 이동할 때 작동합니다.
Martin Berger

저는 iOS 6에 있지만 작동하지 않습니다. "UIViewController * presentedViewController"줄에서 중단됩니다.
Marcel Marino

39

이 답변은 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:^{
            }];
     }];
}

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


감사합니다. 몇 분의 자유 시간을 찾으면 시도해 보겠습니다
Lope 2013 년

@RohanAgarwal 광고 된대로 작동합니다. 여기에서 사용하고 있습니다. 그러나 수락 된 답변의 코드도 구현해야합니다. 그렇지 않으면 작동하지 않습니다.
Dennis Munsie

2
누구든지 동시에 올바른 회전 애니메이션으로이 작업을 수행하는 방법을 알아 냈습니까? 애니메이션없이 세로에서 가로로 전환되는 것을 보는 것은 약간 혼란 스럽습니다. 조금 더 잘 작동하기를 바라면서 작동합니다.
Dennis Munsie

@Craig Watkinson 스토리 보드에서 작동하지 않습니다. 및 presentModalViewController 및 dismissModalViewControllerAnimated는 스피 presentVirecontroller를 사용하는 경우 다음 날 호야 도움을 작동 실 거예요되지 않습니다
Kalpesh

1
ios8 dismissViewControllerAnimated의 경우 충돌이 발생합니다. [NWSAppDelegate sharedInstance] .window.rootViewController = nil; [NWSAppDelegate sharedInstance] .window.rootViewController = previousRootController가 잘 작동합니다.
Alexey 2014 년

36

그래서 세로 모드 만 표시 할 때 동일한 문제가 발생했습니다. 일반적으로, 나는를 만들 것 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);
}

1
내에서 작동하지 않습니다. 나는이 모든 방향에 살고 있고 세계와 코드했다
phil88530을

2
supportedInterfaceOrientations는 BOOL이 아닌 NSUInteger를 반환해야합니다. 참조 developer.apple.com/library/ios/#featuredarticles/...
tomwhipple

그 대답에 대해 다시, 나를 위해, 덕분에 그것 tabbarcontroller 근무
otakuProgrammer

FWIW, 나도이 길을 가야 했어. 감사.
Steve N

15

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;
}

우수한! 이 스레드의 맨 위에 있어야합니다. 이 문제를 해결하는 가장 간단한 방법이기 때문에
알렉스

@Roshan Jalgaonkar In ios 6 그것은 나를 위해 작동하지 않습니다 나는이 UIOrientation을 어떻게 설정할 수 있는지 홈 버튼 아래로 초상화 만 필요합니다 ....
Karthik

@Karthik이 작동하려면 앱의 대상에서 지원되는 회전을 활성화해야합니다.
Alejandro Iván

@ AlejandroIván K thnx
KARTHIK

10

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 등을 재평가하도록 강제합니다.


2
이 중 첫 번째는 iOS 버전에 관계없이 나에게 충돌합니다. 현재가 끝나기 전에 dismiss를 호출해서는 안된다고 말합니다.
arsenius

@arsenius 어떻게 사용하는지 스 니펫을 게시 할 수 있습니까? 애니메이션이 아닌 한 언급 한 문제가 없어야합니다
Rafael Nobre

또한 두 번째 스 니펫을 viewDidAppear에 넣었고 iOS 6에서 내 상황에 도움이되지 않습니다. 질문은 여기에 있습니다 : stackoverflow.com/questions/15654339/…
arsenius

죄송합니다. 여기에 마지막 댓글이 있습니다. iOS 5 코드를 viewDidAppear로 이동하면 다음 출력과 함께 일종의 무한 루프가 생성됩니다.-[UIApplication beginIgnoringInteractionEvents] overflow. 묵살.
arsenius

3

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;
}

1

UISplitViewController 및 UISegmentedController를 사용하는 비교적 복잡한 범용 앱이 있으며 presentViewController. 위에서 제안한 방법을 사용하여 iPhone ios 5 및 6이 정상적으로 작동하도록 할 수 있었지만 어떤 이유로 iPad는 단순히 Landscape로 표시하는 것을 거부했습니다. 마지막으로 장치와 iOS 5 및 6 모두에서 작동하는 간단한 솔루션 (몇 시간 동안 읽고 시행 착오를 거쳐 구현 됨)을 찾았습니다.

1 단계) 컨트롤러에서 필요한 방향을 지정합니다 (위에 언급 된대로 다소간).

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}

-(BOOL)shouldAutorotate
{
    return YES;
}

-(NSUInteger)supportedInterfaceOrientations
{
    NSInteger mask = UIInterfaceOrientationMaskLandscape;
    return mask;

}

2 단계) 간단한 UINavigationController 하위 클래스를 만들고 다음 메서드를 구현합니다.

-(BOOL)shouldAutorotate {
        return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
        return UIInterfaceOrientationMaskLandscape;
}

3 단계) viewController 제시

vc = [[MyViewController alloc]init];
MyLandscapeNavigationController *myNavigationController = [[MyLandscapeNavigationController alloc] initWithRootViewController:vc];
[self myNavigationController animated:YES completion:nil];

이것이 누군가에게 도움이되기를 바랍니다.


1

여기서 지루하지는 않지만 하위 클래스를 공유하는 데 너무 친절합니까? 감사합니다.

편집 : 글쎄, 마침내 해냈고, 하위 클래스는 간단했습니다. 난 그냥 선언했다 navigationControllerAppDelegateUINavigationControllerSubclass대신 기본 UINavigationController, 다음 서브 클래스를 함께 수정 :

- (BOOL)shouldAutorotate {
    return _shouldRotate;
}

를 호출하여 회전하거나 원하지 않는 뷰를 설정할 수 있습니다. viewDidLoad

_navController = (UINavigationController *)self.navigationController;
[_navController setShouldRotate : YES / NO]

이 조정이 다른 사람들에게도 도움이되기를 바랍니다. 팁에 감사드립니다!

팁 : 활용

- (NSUInteger)supportedInterfaceOrientations

따라서 뷰 컨트롤러에서 가로로 원하는 세로보기로 끝나지 않으며 그 반대의 경우도 마찬가지입니다.


0

내가 직접 테스트하지 못했지만, 문서는 지금 그 메소드를 오버라이드 (override) 할 수있는 상태 : supportedInterfaceOrientationspreferredInterfaceOrientationForPresentation.

이러한 방법에서 원하는 방향 만 설정하여 원하는 것을 얻을 수 있습니다.


0

UINavigationController 및 UITabBarController 클래스 내에서 VC를 허용하는 하위 클래스 또는 범주를 사용하는 답변은 잘 작동합니다. 가로 탭 막대 컨트롤러에서 세로 전용 모달을 시작하지 못했습니다. 이 작업을 수행해야하는 경우 애니메이션이 적용되지 않은 모달 뷰를 표시하고 숨기는 트릭을 사용하지만 viewDidAppear 메서드에서 수행합니다 . viewDidLoad 또는 viewWillAppear에서 작동하지 않았습니다.

그 외에도 위의 솔루션은 잘 작동합니다.


0

Monotouch의 경우 다음과 같이 할 수 있습니다.

public override UIInterfaceOrientationMask GetSupportedInterfaceOrientations()
    {
    return UIInterfaceOrientationMask.LandscapeRight;
}

public override UIInterfaceOrientation PreferredInterfaceOrientationForPresentation()
    {
    return UIInterfaceOrientation.LandscapeRight;
}


-1

project.plist로 이동 한 다음 지원되는 인터페이스 방향을 추가 한 다음 세로 (홈 하단 버튼) 및 세로 (홈 상단 버튼) 만 추가하면됩니다.

프로젝트 요구 사항에 따라 방향을 추가하거나 제거 할 수 있습니다.

감사


1
전체 응용 프로그램이 아닌 특정 뷰 컨트롤러에 관한 것입니다.
Muhammad Rizwan 2014-08-20

-2

1) 프로젝트 설정 및 info.plist를 확인하고 원하는 방향 만 선택되었는지 확인합니다.

2) 최상위 뷰 컨트롤러 (내비게이션 컨트롤러 / 탭바 컨트롤러)에 다음 메서드를 추가합니다.

- (NSUInteger) supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait;

}

3) 앱 델리게이트에 다음 메서드를 추가합니다.

- (NSUInteger) supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait;

}

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
    return UIInterfaceOrientationMaskPortrait;

}

-3

ViewController회전하지 않으려 는 각각의 .m 파일에 넣으십시오 .

- (NSUInteger)supportedInterfaceOrientations
{
    //return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft;
    return UIInterfaceOrientationMaskPortrait;
}

자세한 내용은 여기 를 참조하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.