본문

아이폰 회전시에도 동일한 위치에 떠있는 뷰 만들기

지난번에 작성했던 MoviePlayer예제로 살펴보는 아이폰 Media Player Framework #2 : Overlay View에서는 가로모드를 위하여 회전된 서브뷰를 어떻게 만들것이냐에 대해 다루었다. 이번 게시물은 이에 확장되어 모든 방향으로 회전하더라도 동일한 위치에 계속 붙어있는 라벨을 만드는 방법에 대해 설명한다. 

우선 화면의 회전은 크게 Portrait, Landscape Left, Portrait Upside-down, Landscape Right의 네가지의 모드로 구분할 수 있다. 이는 기본 화면에서 90도씩 시계방향으로 회전한것을 의미하며 아래의 그림을 보면 쉽게 이해할 수 있을것이다. 괄호안에 있는 파이(π) 기호는 호도법을 사용하여 중심각을 나타낸것이다.


[그림 1] 화면 회전에 따른 Orientation과 그 수치


1. 우선 화면 회전에 대한 알림을 제공해 달라고 선언해야 한다. 그 후 NotificationCenter를 통해서 이 이벤트를 누가 처리할것인가에 대해서 설정해준다. 여기에서는 screenRotate:를 지정하였다 그리고 프로그램 종료시에는 역시 이들을 해지해 주는것도 잊지 말아야 한다.

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(screenRotate:) name:UIDeviceOrientationDidChangeNotification object:nil];

===============

[[NSNotificationCenter defaultCenter] removeObserver:self];
[[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];


2. 화면 회전이 이벤트가 발생되면 screenRotate:가 불려지게 된다. 이 메소드가 하는일은 Orientation값을 불러 온 후에 그에맞는 Transform을 view라는 뷰에 처리해주고 이를 최상단 윈도우에 추가해 주는것이다. 물론 UIView *view;는 전역변수로 설정되어 있다고 가정한다. 따로 설명할 부분이 있다면, viewRect의 값은 현재 윈도우의 크기를 나타내는것이므로 가로모드일때는 높이와 너비가 서로 바뀐다는 것이다. 또한 Transform의 경우에는 각각의 각도에 맞춰서 값을 곱해주어 회전뷰를 회전시킨다. 물론 맨 마지막의 else는 UIDeviceOrientationPortrait을 의미한다.

- (void) screenRotate:(NSNotification*)notification
{
    UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];    
    UIWindow *window = [[UIApplication sharedApplication] keyWindow];    
    [view removeFromSuperview];
   
    CGRect windowRect = [[UIScreen mainScreen] bounds];
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 100.0f, 20.0f)];
    [label setText:@"Hi there!"];
   
    if( orientation == UIDeviceOrientationLandscapeLeft)
    {
        CGRect viewRect = CGRectMake(0.0f, 0.0f, windowRect.size.height, windowRect.size.width);
        CGAffineTransform transform = CGAffineTransformRotate(CGAffineTransformIdentity, M_PI * 1/2);
       
        view = [[UIView alloc] initWithFrame:viewRect];
        [view setTransform:transform];
    }
    else if ( orientation == UIDeviceOrientationPortraitUpsideDown )
    {
        CGRect viewRect = CGRectMake(0.0f, 0.0f, windowRect.size.width, windowRect.size.height);
        CGAffineTransform transform = CGAffineTransformRotate(CGAffineTransformIdentity, M_PI * 2/2);
       
        view = [[UIView alloc] initWithFrame:viewRect];
        [view setTransform:transform];
    }
    else if ( orientation == UIDeviceOrientationLandscapeRight )
    {
        CGRect viewRect = CGRectMake(0.0f, 0.0f, windowRect.size.height, windowRect.size.width);
        CGAffineTransform transform = CGAffineTransformRotate(CGAffineTransformIdentity, M_PI * 3/2);
       
        view = [[UIView alloc] initWithFrame:viewRect];
        [view setTransform:transform];
    }
    else
    {
        CGRect viewRect = CGRectMake(0.0f, 0.0f, windowRect.size.width, windowRect.size.height);
        view = [[UIView alloc] initWithFrame:viewRect];
    }    

    [view setCenter:window.center];
    [view addSubview:label];
    [label release];
    [window addSubview:view];
    [view release];
}
 

댓글

Holic Spirit :: Tistory Edition

design by tokiidesu. powerd by kakao.