Develop

[ios] iOS 6.0 이상 회전 하기 (이전 버전과 비교 변경 부분)

by hooni posted Jan 27, 2014
?

단축키

Prev이전 문서

Next다음 문서

ESC닫기

크게 작게 위로 아래로 댓글로 가기 인쇄

OS를 업데이트 후 회전이 올바르게 동작하지 않는 것을 보고 당황했습니다.

관련 내용을 찾아보니 어렵지 않게 화면 회전에 대응할 수 있었습니다.

iOS 6.0 이상 및 하위 버전에서 화면 회전을 지원하기 위한 방법을 설명합니다.

iOS 6.0 부터 회전을 지원하는 delegate 메소드가 조금 변경되었습니다.


# iOS 기존 버전에서 화면 회전을 지원하는 코드.


1. window에 view 추가.

[self.window addSubview:viewController.view];


2. UIViewController에 지원할 회전 방향에 대한 delegate 구현

// 자동회전 지원하는 방향 
- (BOOL)shouldAutorotateToInterfaceOrientation:
    (UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait || 
        interfaceOrientation == UIInterfaceOrientationLandscapeLeft || 
        interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}


3. UIViewController에서 회전하기 전/후 호출되는 delegate 구현

- (void)willRotateToInterfaceOrientation:
    (UIInterfaceOrientation)toInterfaceOrientation
    duration:(NSTimeInterval)duration
{
    // 회전하기 전에 호출됩니다.
}

- (void)didRotateFromInterfaceOrientation:
    (UIInterfaceOrientation)fromInterfaceOrientation
{
   // 회전 후에 호출됩니다.
}


shouldAutorotateToInterfaceOrientation의 UIInterfaceOrentation 파라미터 타입은..

다음과 같이 enum 타입 상수로 선언되어 있습니다.

typedef NS_ENUM(NSInteger, UIInterfaceOrientation) {
    UIInterfaceOrientationPortrait =
        UIDeviceOrientationPortrait,

    UIInterfaceOrientationPortraitUpsideDown =
        UIDeviceOrientationPortraitUpsideDown,

    UIInterfaceOrientationLandscapeLeft =
        UIDeviceOrientationLandscapeRight,

    UIInterfaceOrientationLandscapeRight =
        UIDeviceOrientationLandscapeLeft
};



# iOS 6.0 이상에서는 무엇이 바뀌었을까요?

>> 위의 1번과 2번이 변경되었습니다.


1. window에 rooViewController 추가.

self.window.rootViewController = viewController;

2. UIViewController에 지원할 회전 방향에 대한 delegate 구현

//  자동회전 지원 유무 
- (BOOL) shouldAutorotate {
      return YES; 
}

// 지원하는 회전방향 
- (NSUInteger)supportedInterfaceOrientations {
    return (1 << UIInterfaceOrientationPortrait) |
        (1 << UIInterfaceOrientationLandscapeLeft) |
        (1 << UIInterfaceOrientationLandscapeRight);
}


기존에 2가지 역할을 하던 메소드가 자동회전 유무와 회전하는 방향을 반환하는 메소드로 각각 분리되었습니다.

또 지원하는 회전방향의 경우, NSUInteger 반환값으로 변경되었는데 이 값은 아래와 같이 지원하는 회전방향의 비트가 셋팅된 비트 플래그 값입니다.

typedef NS_OPTIONS(NSUInteger, UIInterfaceOrientationMask) {
    UIInterfaceOrientationMaskPortrait =
        (1 << UIInterfaceOrientationPortrait),

    UIInterfaceOrientationMaskLandscapeLeft =
        (1 << UIInterfaceOrientationLandscapeLeft),

    UIInterfaceOrientationMaskLandscapeRight =
        (1 << UIInterfaceOrientationLandscapeRight),

    UIInterfaceOrientationMaskPortraitUpsideDown =
        (1 << UIInterfaceOrientationPortraitUpsideDown),

    UIInterfaceOrientationMaskLandscape =
        (UIInterfaceOrientationMaskLandscapeLeft |
        UIInterfaceOrientationMaskLandscapeRight),

    UIInterfaceOrientationMaskAll =
        (UIInterfaceOrientationMaskPortrait |
        UIInterfaceOrientationMaskLandscapeLeft |
        UIInterfaceOrientationMaskLandscapeRight |
        UIInterfaceOrientationMaskPortraitUpsideDown),

    UIInterfaceOrientationMaskAllButUpsideDown =
        (UIInterfaceOrientationMaskPortrait |
        UIInterfaceOrientationMaskLandscapeLeft |
        UIInterfaceOrientationMaskLandscapeRight),
};

1을 UIInterfaceOrentation 상수값 만큼 왼쪽으로 시프트해주면, 해당하는 방향의 비트를 셋팅할 수 있지요.


또 한가지 중요한 사항은,

커스텀 UINavigationController와 UITabBarController를 사용한 경우, (상속해서 사용하는 경우도 포함)

이 커스텀 클래스의 회전 지원 delegate 메소드에서는 topViewController의 회전지원 delegate 메소드로 위임해야 한다는 것입니다.

아래 코드를 참고

...
- (BOOL) shouldAutorotate {
    return [topViewController shouldAutorotate];
}
...



# iOS 6.0 이상 및 하위 버전에서 화면 회전을 지원하는 코드

위의 설명들을 정리하여,

iOS 6.0 이상 및 하위버전에서 화면 회전을 올바르게 처리하기 위한 코드입니다.

- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    ...
    // iOS6.0 이상
    NSString *currentVersion = [[UIDevice currentDevice] systemVersion];
    
    NSLog(@"%@", currentVersion);
    
    if ( [currentVersion compare:@"6.0" options:NSNumericSearch] !=
        NSOrderedAscending )
    {
        self.window.rootViewController = self.viewController;
    } else {
        // 하위버전
        [self.window addSubview:self.viewController.view];
    }
    [self.window makeKeyAndVisible];
    return YES;
}

#pragma mark - 회전지원 iOS6.0 이상

// 자동회전 지원유무
- (BOOL) shouldAutorotate
{
    return YES;
}

// 회전방향 지원유무
- (NSUInteger)supportedInterfaceOrientations
{
    return (1 << UIInterfaceOrientationPortrait) |
           (1 << UIInterfaceOrientationPortraitUpsideDown) |
           (1 << UIInterfaceOrientationLandscapeLeft) |
           (1 << UIInterfaceOrientationLandscapeRight);
}

#pragma mark - 회전지원 iOS6.0 미만 

// 회전방향 지원유무
- (BOOL)shouldAutorotateToInterfaceOrientation:
    (UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft ||
            interfaceOrientation == UIInterfaceOrientationLandscapeLeft ||
            interfaceOrientation == UIInterfaceOrientationLandscapeRight ||
            interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown
            );
}


#pragma mark - 회전 델리게이트 

// 공통
- (void)willRotateToInterfaceOrientation:
    (UIInterfaceOrientation)toInterfaceOrientation
    duration:(NSTimeInterval)duration
{
    // 회전하기 전에 호출됩니다.
}

- (void)didRotateFromInterfaceOrientation:
    (UIInterfaceOrientation)fromInterfaceOrientation
{
    // 회전 후에 호출됩니다.
}


[출처] http://hiddenviewer.tistory.com/207