2009-02-21 3 views
5

사용자의 결정에 의존하는 몇 가지 유효성 검사 (예 : 지출 한도를 초과하여 구매를 승인하는 경우)를 실행하고 실패한 경우 '완료'작업을 거부해야합니다.iPhone의 진정한 UIAlertView?

그러나 다른 언어 (예 : showmessage, alert() 등)와 같은 모달 동작을 수행 할 수없는 것처럼 보이며 모든 것은 대리인이 담당합니다.

하지만 무엇을해야할지 모르겠다. 사용자가 "완료"버튼을 누르면 프로그램에서 "이거 확실합니까?"라고 묻습니다. 그리고 그는 "취소"라고 말하면 흐름이 계속되고보기가 뒤로 밀렸습니다!

어떻게 이것이 코코아 세계에서 해결 되었습니까?

답변

7

해결 방법은 이 아니므로에 대한 논리는 두 부분으로 나뉩니다. 사용자가 취소를 클릭하면 두 번째 부분을 실행하지 마십시오. 사용자가 확인/계속을 클릭하면 두 번째 부분을 실행합니다.

주 스레드를 차단하여 발생하는 주요 문제는 주 스레드가 이벤트를 처리한다는 것입니다. 이벤트를 처리하는 고전적인 방법은 이상한 이벤트 처리 버그를 유발할 수 있습니다. 하나의 이벤트 루프가 없기 때문에 여러 개의 이벤트 루프가 서로 내부에 포함되어 있기 때문입니다.

델리게이트를 사용하면 하나의 이벤트 루프 (UIApplicationMain을 통해 호출 됨)를 활용할 수 있으며 이러한 이벤트 처리 기이함이 전혀 발생하지 않습니다.

+3

즉, 코드를 완전히 재구성하고 출시 예정일이 오기 전에 사용자가 크고 복잡한 계산 도중에 한꺼번에 확인을 요청하지 않도록기도하십시오. 지역 변수의. – GeneralMike

+1

+1. –

0

응용 프로그램의 상태를 함수의 변수가 아닌 다른 곳에 보관하십시오. 예를 들어, 내 앱 중 하나에 개인 정보 보호 정책에 동의했는지 여부를 나타내는 프로필 문자열이 있습니다.

0

저는 MonoTouch 질문으로이 질문을 만났습니다. 해결책을 연구하는 동안이 열린 질문을 만났습니다.

짧은 대답은 네가 가능하다는 것입니다. 다음 샘플은 iPhone에서 MonoTouch 및 C#을 사용하여 수행하는 방법을 보여줍니다. 그러나 Objective-C에도 동일한 원칙이 적용됩니다.

이렇게하려면 메인 루프를 수동으로 실행해야합니다. 나는 mainloop을 직접 멈출 수 없었기 때문에 대신 0.5 초 동안 mainloop을 실행하고 사용자가 응답 할 때까지 기다린다.

int WaitForClick() 
{ 
    int clicked = -1; 
    var x = new UIAlertView ("Title", "Message", null, "Cancel", "OK", "Perhaps"); 
    x.Show(); 
    bool done = false; 
    x.Clicked += (sender, buttonArgs) => { 
     Console.WriteLine ("User clicked on {0}", buttonArgs.ButtonIndex); 
    clicked = buttonArgs.ButtonIndex; 
    };  
    while (clicked == -1){ 
     NSRunLoop.Current.RunUntil (NSDate.FromTimeIntervalSinceNow (0.5)); 
     Console.WriteLine ("Waiting for another 0.5 seconds"); 
    } 

    Console.WriteLine ("The user clicked {0}", clicked); 
    return clicked; 
} 
3

체크 아웃 : : http://code.google.com/p/modal-uialertview-uiactionsheet/

그것으로 당신은 같은 일을 할 수있다 :

UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:nil delegate:nil cancelButtonTitle:@"Cancel" destructiveButtonTitle:@"Delete" otherButtonTitles:nil]; 
if ([actionSheet showModalInView:self.view] == actionSheet.destructiveButtonIndex) { 
    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:@"Do you want to delete this file?" delegate:nil cancelButtonTitle:@"No" otherButtonTitles:@"Yes", nil]; 
    if ([alertView showModal]!= alertView.cancelButtonIndex) { 
     // Delete the file 
    } 
} 
+0

이 방법은 private 메소드 [alert setRunsModal : YES]보다 효과가 있습니다. Apple의 구현을 사용하면 두 번째를 표시 할 때 첫 번째 경고가 취소되기 때문입니다. 그러나이 구현에서는 중첩 된 경고를 가질 수 있습니다. – malhal

0

은 다음 함수는 위의 방법으로 모달 쿼리를 구현할 수있는 방법을 보여줍니다

나는 일반적으로 싸워서는 안되며 일반적으로 그렇게하지 말아야한다는 NilObject에 동의합니다. 하지만 난 AddressBookUI 프레임 워크를 사용하고 내가 대리자 방법에있을 때

- (BOOL)unknownPersonViewController:(ABUnknownPersonViewController *)personViewController shouldPerformDefaultActionForPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier 

는 정말 그들이에 클릭 할 때 응용 프로그램을 떠날 것, 예를 들어, 그들이 사용자에게 경고하고 싶습니다 이 주소는지도 앱에서 시작됩니다. MapKit을 사용하여 내지도를 만들었지 만 전체지도 응용 프로그램을 재현 할 수있는 인내심이 없어 (사용자가 다른 주소에서 길 찾기를 할 수있게 해줌) shouldPerformDefaultAction 작업을 시작하고 시작합니다. 지도 앱이지만 사용자에게 앱을 떠날 것이라고 경고 할 방법이 없습니다.

정말 애플이 해킹하지 않고 아주 기본적인 모델 인 UIAlertView를 제공하기를 바랍니다. 이것은 어리 석다.