본문

MoviePlayer예제로 살펴보는 아이폰 Media Player Framework #2 : Overlay View

이전 페이지에서 있던 화면에 보면(굳이 다시 이미지를 올려야 하나 생각이 되어 올리지 않는다), 동영상 재생을 위해 Play Movie라는 버튼이 있음을 알 수 있다. 이 버튼을 누르게 되면 MyMovieViewController.m의 60번째 줄에 있는 playMovieButtonPressed:가 실행이 되며 그의 코드는 아래와 같다.

1. 동영상 위에 오버레이 뷰 추가하기
MyMovieViewController.m : 60
// 현재 어플리케이션의 메인 델리게이트(MoviePlayerAppDelegate)를 가져온다
MoviePlayerAppDelegate *appDelegate = (MoviePlayerAppDelegate *)[[UIApplication sharedApplication] delegate];

// MoviePlayerAppDelegate에 있는 initAndPlayMovie:를 실행하여 MPMoviePlayerController객체를 MyMovieViewController의 localMovieURL:에서 받아온 URL값과 함께 초기화하고 동영상을 재생시킨다
[appDelegate initAndPlayMovie:[self localMovieURL]];

// 현재 애플리케이션에 떠있는 모든 윈도우를 가져와 배열로 저장한다
NSArray *windows = [[UIApplication sharedApplication] windows];

// 만약 윈도우가 2개 이상이라면(메인 윈도우+동영상 윈도우)
if ([windows count] > 1)
{
    // 현재 애플리케이션에서 가장 위에 떠있는 윈도우(keyWindow, 동영상 윈도우)를 불러온다
    UIWindow *moviePlayerWindow = [[UIApplication sharedApplication] keyWindow];

    // 동영상윈도우의 서브뷰에 오버레이 뷰를 추가함으로서 동영상 위에 뷰가 보이도록 한다
    [moviePlayerWindow addSubview:self.overlayView];
}


[그림 1] MainWindow.xib에 등록되어있는 오버레이 뷰


위의 코드를 통해 우선 동영상 위에 원하는 뷰를 얹는것이 완료되었다. 이미 MainWindow.xib에 오버레이 뷰가 등록되어 있으며 이는 overlayView 아웃렛으로 연결(또한 이 뷰는 MyOverlayView클래스를 갖는다)되어 있기 떄문에 마지막 줄이 가능했던 것이다. 오버레이 뷰는 xib가 처리될 때 awakeFromNib이 호출되며, 동영상이 가로모드로 전체화면으로 재생될것이므로 이때 마찬가지로 오버레이 뷰도 가로로 보이도록 처리를 해준다. 이는 MyOverlayView.m의 63번째 줄의 awakeFromNib:에 정의되어 있다. 
 
2. 가로모드를 위해 오버레이 뷰 회전하기
MyOverlayView.m : 63
// 현재 view의 transform 저장.
CGAffineTransform transform = self.transform;

// 90도 회전시킨다.(행렬곱을 사용한다는데 머리아파지므로 생략..) 
transform = CGAffineTransformRotate(transform, (M_PI / 2.0));

// 기기의 스크린을 나타내는 스크린 객체를 불러온다. bounds도 있고 applicationFrame있는데 지금은 전체화면이니까.
UIScreen *screen = [UIScreen mainScreen];

// 의미는 잘 모르겠는데 이곳을 확인하면 도움이 될것같다.
transform = CGAffineTransformTranslate(transform, ((screen.bounds.size.height) - (self.bounds.size.height))/2, 0);

// 변경된 trnasform을 view에 설정
self.transform = transform;

// 현재 프레임의 상위뷰에 대한 x좌표를 변경한다. frame과 bounds의 차이는 이곳을 확인
CGRect newFrame = self.frame;
newFrame.origin.x = 190;
self.frame = newFrame;
 

이렇게 오버레이 뷰의 추가가 완료되면 이젠 오버레이 뷰에서 하는 일들에 대해 알아볼 시간이다. 우선 [그림 1] 에서 보다시피 오버레이 뷰의 button을 누르면 MyViewController의 overlayViewButtonPress:가 호출됨을 알 수 있다. 그런데 예제상으로는 이것이 아무런 일도 하지 않는다, 또한 MyOverlayView.m의 87번째 줄에는 touchesBegan: 메소드가 있다. 이는 MyOverlayView가 UIView를 상속하기 때문으로, 이는 뷰에서 일어나는 터치에 대한 이벤트를 처리할 수 있도록 해준다. 즉, 이 어플리케이션에서는 뷰 자체에 있는 이벤트와, 뷰 내의 버튼에서 일어나는 이벤트 둘을 분리해서 처리하고 있다.

3. 뷰에서 일어나는 터치 이벤트 처리하기
MyOverlayView.m : 87
// 액션의 선언은 (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
UITouch* touch = [touches anyObject];

// 터칭이 시작되었을 때

if (touch.phase == UITouchPhaseBegan)
{
    // NotificationCenter를 불러와서 OvelayViewTouchNotification을 뿌려준다.
    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];

    // NSString * const OverlayViewTouchNotification = @"overlayViewTouch";으로 설정되어 있다.
    [nc postNotificationName:OverlayViewTouchNotification object:nil];
}    

MyViewController.m : 194
// OverlayViewTouchNotification 이벤트가 발생하면 이를 받아 overlayViewTouches:를 호출한다, dealloc시 remove를 잊지않아야 한다.
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(overlayViewTouches:) name:OverlayViewTouchNotification object:nil];

댓글

Holic Spirit :: Tistory Edition

design by tokiidesu. powerd by kakao.