[iOS] UIAlertView - didDismissWithButtonIndex 이벤트 문제

2012. 12. 4. 10:25Scrapbook/개발 및 프로그래밍

반응형

 UIAlertView의 Delegate 이벤트가 제대로 진행되지 않아 며칠간의 디버깅(삽질)끝에 찾아냈다.

개발에서 노하우 정말 중요하다.

 

clickedButtonAtIndex ==> didDismissWithButtonIndex 로 수정하여 해결.

 

아래는 고마운 글.


문 제
UIAlertView 메세지를 출력하는 도중 Home 버튼과 같이 예외 상황이 경우 UIAlertView의 Delegate 이벤트가 제대로 진행되지 않은 현상

현 상
문제 소스

- (void) spotDownloader:(SpotDownloader *)downloader didDownloadAll:(int)allSpot
{
//마지막에
if(NaNetworkReachable() == NO)
{
[i_downloader stop];
NaMessageViewWithOneButton(Na_STR_ERROR_NO_NETWORK, @"확인", self);
return;
}

i_progressView.downloadAllNum = allSpot+i_downedNum;
i_progressView.downloadNum = allSpot+i_downedNum;
i_bDownloading = NO;
i_downloading = NO;

WSTown *town = [getThemeCountWithTownId(i_downloadTownId, i_downloadCityId) retain];

[SQLiteForWingSpoon updateTownInformation:i_downloadTownId
spotCount:town.i_spotCount
themeCountArray:town.i_themeArray
updateDate:nil valid:2];
[SQLiteForWingSpoon updateCityInformation:i_downloadCityId
valid:2];

[town release];

NaMessageViewWithYesNoButtonWithDelay([NSString stringWithFormat: Na_STR_OK_DOWNLOAD, [i_downloadTargetTown i_name] ], self, 1, 0.1);
}



다운로드를 받고 완료 메세지(NaMessageViewWithYesNoButtonWithDelay)를 출력하는 도중 Home버튼을 누르게 되면 아래와 같은 순서로 이벤트가 발생하였다.

1. 다운로드 완료 처리 중(spotDownloader 진행 중)
2. 홈 버튼 클릭
2. UIAlertViewDelegate - willPresentAlertView (Background로 가기전에 AlertView가 준비상태로 돌입)
3. AppDelegate - applicationDidEnterBackground (Background 상태)
4. 앱 재 실행
5. UIAlertViewDelegate - didPresentAlertView (Foreground 이전에 AlertView가 표시)
6. AppDelegate - applicationWillEnterForeground (Foreground 상태가 됨)
6. UIAlertViewDelegate - didDismissWithButtonIndex (AlertView가 저절로 닫힘)

이런순으로 Delegate가 진행되어 문제가 발생되었다. 즉 Foreground 이전에 didPresentAlertView가 호출되어 이미 메세지가 뜬 상태로 있다가 Foreground 호출 이후 didDissmissWithButtonIndex가 호출되어 메세지 창이 저절로 닫혀버리는 현상이다. 더욱이 이런게 닫힌 창이 다른 UIAlertView가 호출될 때 갑자기 나타나는 것이다. 그로 인해 원래 UIAlertView에서 호출되어 처리되어야 하는 View가 아닌 다른 view에서 호출되어 BAD_EXCEPTION 발생하는 문제가 생겼다. (어떤 경우에는 6번 과정 이후 자동으로 다시 willPresentAlertView가 호출되어 다시 출력되어 문제가 안생기는 경우도 있으나 위 상태에서 중단 되는 경우가 문제 였다)


해결방법

1. didDismissWithButtonIndex 이벤트가 발생될 때 매개변수로 넘어오는 alertView의 객체 상태로 비정상 닫기 인지 정상 닫기 인지 구분하는 방법을 찾았다.

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

alertView == nil 인 경우 정상 닫힘
alertView != nil 인 경우 비정상 닫힘

2. UIAlertView 내 dismissWithClickedButtonIndex 메시지를 호출하여 AlertView를 다시 출력 안되게끔 막는다.
-> UIAlertView 내 메시지들을 찾아보다가 위 메시지의 역할이 사용자의 Action 없이 AlertView를 닫히게하는 기능이 있다는 것을 깨닫고 비정상 닫힌 경우 위 메시지를 호출하여 다른 UIAlertView와 중복 호출이 안되게 끔 방지하였다

3. 마지막으로 닫혀버린 UIAlertView 메시지를 다시 출력하여 사용자가 AlertView 이상 동작을 못느끼게 재실행한다

- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex // after animation
{
if(alertView.superview != nil){
// 기존에 비정상 UIAlertView를 오작동 출력을 방지함
[alertView dismissWithClickedButtonIndex:buttonIndex animated:NO];
// 메시지 재출력
NaMessageViewWithYesNoButton([NSString stringWithFormat: Na_STR_OK_DOWNLOAD, [i_downloadTargetTown i_name] ], self, 1);

}
}


출처: http://devnote2.tistory.com/32

 

반응형