본문 바로가기
프로그래밍/iOS

CFRunLoopRun() 를 이용한 AlertView 만들기

by 백룡화검 2013. 1. 9.

출처 : http://cafe.naver.com/mcbugi/246495


CFRunLoopRun() 를 이용한 AlertView 만들기

: Block이나 Delegate 없이 버튼 Index를 바로 받아 올 수 없을까 ?

UIAlertView 클래스는 사용자에게 alert 메시지를 발생하게 합니다. 참으로 꼭 필요한 클래스가 아닐 수 없습니다. 하지만 버튼 index를 콜백받는 메소드를 delegate로 지정하여 따로 코드를 작성하는 일이 여간 귀찮은 것이 아니라 할 수 없으며, Block 코드(iOS4이상)가 등장했을 때, 이것을 좀더 편하게 하기 위해 UIAlertView를 Block 코드로 리턴받는 메소드가 생겨났을 정도 입니다.

UIAlertView+Block 코드를 보신분은 아시겠지만, 정말 단순한 발상 (UIAlertView를 Delegate 안쓰고 바로 버튼 Index를 받을 수 없을까?) 에서 시작된 코드가 생각보다 많고 복잡하게 구성되어 있습니다. Block 코드라는 것이 익숙치 않은 분들에게는 정말 복잡하기 짝이 없는 코드라서 그렇습니다.

그럼 Block 코드를 사용하지 않으면서, Delegate를 사용하지도 않고, Alert를 Show하는 코드 다음줄에 바로 결과를 알수 없을까? 라는 정의를 다시 들어가겠습니다.

---------------------------------------------------------------------------------------------------------------------------------------------------------
1. Show
2. Event Loop (message dispatcher, message loop, message pump, or run loop)
{
    2-1. Clicked Button -> Event Loop Break;
}

while (조건) 
{
    Event Handling
}
---------------------------------------------------------------------------------------------------------------------------------------------------------
위와 같은 식으로는 할 수 없을까?

Event Loop를 Cocoa에서 제공해주기 때문에 제공되는 메소드 'CFRunLoopRun', 'CFRunLoopStop' 로 다음과 같이 코딩하였습니다.

기존 클래스를 상속받아 'JKAlertView' 라는 클래스를 제작합니다.

[코드]

@implementation JKAlertView


/**

 Modal 형태로 대화상자를 띄우는 메서드

 @return 버튼 Index

 */

- (NSInteger)show

{

    _buttonIndex  = -1;

    [self setDelegate:self];


    [super show];

    

    // Event Loop

    CFRunLoopRun();

    

    // 버튼 Index 반환

    return _buttonIndex;

}


#pragma mark -

#pragma mark UIAlertViewDelegate

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex

{

    _buttonIndex = buttonIndex;

    

    // Event Loop 종료

    CFRunLoopStop(CFRunLoopGetCurrent());

}


@end


[사용]

JKAlertView * alert = [[JKAlertView alloc] initWithTitle:@"JKAlertView" message:@"사용법" delegate:nil cancelButtonTitle:@"취소" otherButtonTitles:@"확인", nil];

if (1 == [alert show])

{

    // 인덱스 1번 버튼 눌렸을 때

}

[alert release];


위와 같이 사용하시면 됩니다. 기존 사용법과 동일한 대신, show에서 바로 버튼 Index를 받아오시면 됩니다.