1

두 개의보기 컨트롤러를 동시에 표시하는 탐색 컨트롤러가 있습니다. 그들은 계층화되어 있으며 가장 앞쪽에있는 컨트롤러를 아래로 드래그하여 아래의 컨트롤러를 나타낼 수 있습니다. 아래에서 볼 수 있듯이 앱은 뒷면의 뷰가 공개 될 때만 앱이 인터페이스 방향을 허용하도록 내 애플리케이션 위임이 구성됩니다.탐색 컨트롤러의 일부보기 컨트롤러가 회전하지 못하도록합니다.

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window 
{ 
    if (self.revealNavigationController.isViewRevealed) 
    { 
     return UIInterfaceOrientationMaskAllButUpsideDown; 
    } 

    return UIInterfaceOrientationMaskPortrait; 
} 

당연히 이것은 전면 및 장치가 회전하지만 후면 뷰 컨트롤러 회전에만 관심이 때 회전하도록 다시보기 제어기 모두를 야기한다. 전면보기 컨트롤러에서 회전을 완전히 비활성화 할 수있는 방법이 있습니까?

+0

인가 전화 (이것은 미안 해요 다시 찾을 지금 드릴 수 없습니다에 StackOverflow에 다른 답변, 영감) 사용자가 뒤로보기를 표시하고 옆으로 회전 한 다음 숨기고 기본보기가 여전히 옆으로 보이거나 화면이 꺼져 있어도 기본보기가 회전되는 문제는 무엇입니까? – axiixc

+0

@axiixc 화면이 꺼져있을 때 기본보기가 회전되는 것이 문제입니다. 뷰 컨트롤러는 방향 변경을 지원하지 않으므로 다시보기를 표시하고 가로로 회전하고 세로로 회전하여 다시보기를 숨기면 기본보기가 표시되고 기본보기가 엉망이됩니다. 이상적으로는 기본보기를 회전하는 것이 불가능하기를 바랄 것입니다. 이렇게하면 두 가지 문제점을 모두 해결할 수 있습니다. 따라서 사용자가 백 뷰를 표시하고 옆으로 회전하여 숨기면 기본 뷰는 여전히 세로입니다. – simonbs

답변

0

axiixc에서 제안한 해결책은 일반적으로 문제에 따라 다르므로 look at his answer이어야합니다. 그러나 이것은 내 문제를 해결하지 못했습니다. 나는 UINavigationController을 가지고 있는데, 뷰 컨트롤러의 뷰를 인덱스 0의 서브 뷰로 삽입했다.이 방법은 뷰가 뒤쪽에있을 것이다. 그 다음에 나는 UINavigationBar을 드래그 가능하게 만들었습니다. 드래그 할 때 뒤쪽에있는 뷰를 드러내도록했습니다. 그러면 가장 앞쪽에있는보기가 내비게이션 막대와 함께 움직입니다. axiixc에서 제안한 것처럼 iOS 5가 도입 된 View Controller Containment API로이 기능을 사용할 수 없었습니다.

대신 내비게이션 컨트롤러에서보기를 제거하고 앱이 시작될 때 UIWindow에 직접 추가했으며이보기의 회전을 직접 처리하고 다른 모든보기에서 순환 게재를 사용하지 않도록 설정했습니다 (즉, 네비게이션 컨트롤러).

내가 UIDeviceOrientationDidChangeNotification에 등록 된 바로 그 후, 그 다음

self.revealViewController = [[RevealViewController alloc] init]; 
[self.window insertSubview:self.revealViewController.view atIndex:0]; 

-application:didFinishLaunchingWithOptions:에서보기를 추가하는 방법입니다.

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didRotate:) name:UIDeviceOrientationDidChangeNotification object:nil]; 

didRotate:은 다음과 같습니다

- (void)didRotate:(NSNotification *)notification 
{ 
    // Only rotate if the view is revealed 
    if (self.revealNavigationController.isViewRevealed) 
    { 
     UIDeviceOrientation orientation = [UIDevice currentDevice].orientation; 
     [self updateForDeviceOrientation:orientation animated:YES]; 
    } 
} 

내가 -updateForDeviceOrientation:animated:

- (void)updateForDeviceOrientation:(UIDeviceOrientation)orientation animated:(BOOL)animated 
{ 
    CGFloat degrees = 0.0f; 
    switch (orientation) 
    { 
     case UIDeviceOrientationLandscapeLeft: 
      degrees = 90.0f; 
      break; 
     case UIDeviceOrientationLandscapeRight: 
      degrees = -90.0f; 
      break; 
     case UIDeviceOrientationPortrait: 
      degrees = 0.0f; 
      break; 
     default: 
      break; 
    } 

    CGFloat duration = (animated) ? [UIApplication sharedApplication].statusBarOrientationAnimationDuration : 0.0f; 

    __weak typeof(self) weakSelf = self; 
    [UIView animateWithDuration:duration animations:^{ 
     // Rotate view 
     weakSelf.revealViewController.view.transform = CGAffineTransformIdentity; 
     weakSelf.revealViewController.view.transform = CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(degrees)); 

     // Resize view for rotation 
     CGFloat width, height; 
     if (UIDeviceOrientationIsLandscape(orientation)) 
     { 
      width = MAX(CGRectGetWidth(weakSelf.revealViewController.view.bounds), CGRectGetHeight(weakSelf.revealViewController.view.bounds)); 
      height = MIN(CGRectGetWidth(weakSelf.revealViewController.view.bounds), CGRectGetHeight(weakSelf.revealViewController.view.bounds)); 
     } 
     else 
     { 
      width = MIN(CGRectGetWidth(weakSelf.revealViewController.view.bounds), CGRectGetHeight(weakSelf.revealViewController.view.bounds)); 
      height = MAX(CGRectGetWidth(weakSelf.revealViewController.view.bounds), CGRectGetHeight(weakSelf.revealViewController.view.bounds)); 
     } 

     CGSize newSize = CGSizeMake(width, height); 

     CGRect viewBounds = weakSelf.revealViewController.view.bounds; 
     viewBounds.size = newSize; 
     weakSelf.revealViewController.view.bounds = viewBounds; 

     CGRect viewFrame = weakSelf.revealViewController.view.frame; 
     viewFrame.size = newSize; 
     weakSelf.revealViewController.view.bounds = viewFrame; 
    }]; 
} 
0

예, UIViewController에서 -supportedInterfaceOrientations 메서드를 살펴보십시오. UIViewController 하위 클래스에서 지원할 방향을 지정하는 UIInterfaceOrientationMask 비트 마스크를 반환합니다.

+0

필자는 가장 앞쪽에있는 컨트롤러 중 하나에서'-supportedInterfaceOrientations'의'-shouldAutorotate'와'UIInterfaceOrientationMaskPortrait'에'NO'를 반환하려고했습니다. '-supportedInterfaceOrientations'는 뷰가 표시되지만 회전이 아니라면 호출되지만, 무시됩니다. 뷰 컨트롤러는 여전히 뷰를 회전시키고 가로 방향의 자동 레이아웃 제약 조건을 만족하려고 시도합니다. – simonbs

+0

'-shouldAutorotate'는 호출되지 않습니다. – simonbs

1

iOS5에 추가 된보기 컨트롤러 포함 API를 사용해야합니다. 기본적으로, 회전 이벤트에 더 이상 참여시키지 않으려면 하나의보기 컨트롤러를 제거하고 준비가 완료되면 다시 추가하십시오. 샘플은 가장 좋은 건 중 하나)처럼 해킹을 사용되도록 당신이 알 수 있습니다 그러나

@implementation AXRotationDemoViewController 

- (id)init 
{ 
    if ((self = [super init])) 
    { 
     self.oneViewController = [[AXLoggingViewController alloc] init]; 
     self.oneViewController.interfaceOrientations = UIInterfaceOrientationMaskPortrait; 

     self.twoViewController = [[AXLoggingViewController alloc] init]; 
     self.twoViewController.interfaceOrientations = UIInterfaceOrientationMaskAllButUpsideDown; 
    } 

    return self; 
} 

- (void)viewDidLoad 
{ 
    [self.oneViewController willMoveToParentViewController:self]; 
    [self addChildViewController:self.oneViewController]; 
    [self.view addSubview:self.oneViewController.view]; 
    [self.oneViewController didMoveToParentViewController:self]; 

    [self.twoViewController willMoveToParentViewController:self]; 
    [self addChildViewController:self.twoViewController]; 
    [self.view addSubview:self.twoViewController.view]; 
    [self.twoViewController didMoveToParentViewController:self]; 

    self.oneViewController.view.backgroundColor = [UIColor redColor]; 
    self.twoViewController.view.backgroundColor = [UIColor greenColor]; 

    UIButton * showBackButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 
    [showBackButton setTitle:@"Toggle Back/Front" forState:UIControlStateNormal]; 
    [showBackButton addTarget:self action:@selector(_toggle:) forControlEvents:UIControlEventTouchUpInside]; 
    [showBackButton sizeToFit]; 
    showBackButton.center = self.view.center; 
    [self.view addSubview:showBackButton]; 
} 

- (void)_toggle:(id)sender 
{ 
    if ([self.childViewControllers containsObject:self.oneViewController]) 
    { 
     [self.oneViewController.view removeFromSuperview]; 
     [self.oneViewController removeFromParentViewController]; 
    } 
    else 
    { 
     [self.oneViewController willMoveToParentViewController:self]; 
     [self addChildViewController:self.oneViewController]; 
     [self.view addSubview:self.oneViewController.view]; 
     [self.oneViewController didMoveToParentViewController:self]; 

     UIWindow * window = self.view.window; 
     UIViewController * hack = window.rootViewController; 
     window.rootViewController = nil; 
     window.rootViewController = hack; 
    } 
} 

- (void)viewDidAppear:(BOOL)animated 
{ 
    [super viewDidAppear:animated]; 

    CGRect halfScreenFrame = self.view.bounds; 
    halfScreenFrame.size.height /= 2; 

    self.oneViewController.view.frame = halfScreenFrame; 
    self.twoViewController.view.frame = CGRectOffset(halfScreenFrame, 0, halfScreenFrame.size.height); 
} 

- (NSUInteger)supportedInterfaceOrientations 
{ 
    if ([self.childViewControllers containsObject:self.oneViewController]) 
     return self.oneViewController.supportedInterfaceOrientations; 

    return self.twoViewController.supportedInterfaceOrientations; 
} 

@end 

는, 당신은 supportedInterfaceOrientations의 값을 변경 한 정말 아이폰 OS를 알 수있는 공식적인 방법이 없습니다 ... 것 위의 예에서 iOS가 모든 것을 다시 실행하도록하거나 b) 기기가 이미 다시 세로로 표시 될 때까지 사용자가 다시보기를 닫지 않도록합니다.

여기에 설명 된 내용이 충분하지 않은 경우 여기에 나와있는 sample입니다.

+0

이것은 이상적인 접근 방법이지만이 경우에는 제대로 작동하지 않습니다. 내 솔루션은 http://stackoverflow.com/a/16354167/486845를 참조하십시오. – simonbs