2014-12-24 6 views
44

SDK 6.0을 기반으로하는 오래된 iOS 프로젝트를 유지 관리하고 있습니다.UIActionSheet를 대체하기 위해 UIAlertController를 사용하는 방법은 무엇입니까?

이 프로젝트에 대한 방법은 콤보 상자를 표시하는 데 사용됩니다

-(void) showComboBox:(UIView*)view:withOptions:(NSDictionary*)options

을했다. 목표를 달성하기 위해 iOS8에서 더 이상 사용되지 않는 UIActionSheet를 사용했습니다.

내 솔루션은 다음과 같이이다 :

 if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber10_8) { 
     UIAlertController* alertController = [UIAlertController 
      alertControllerWithTitle:@"title" 
      message:@"message" 
      preferredStyle:UIAlertControllerStyleActionSheet]; 

     UIAlertAction* item = [UIAlertAction actionWithTitle:@"item" 
      style:UIAlertActionStyleDefault 
      handler:^(UIAlertAction *action) { 
      //do something here 
      //inform the selection to the WebView 
      ... 
      [alertController dismissViewControllerAnimated:YES completion:nil]; 
     }]; 

     UIAlertAction* cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { 
      [alertController dismissViewControllerAnimated:YES completion:nil]; 
     }]; 

     [alertController addAction:item]; 
     [alertController addAction:cancelAction]; 
     //I am not sure whether it's the right way 
     if ([view.nextResponder isKindOfClass:UIViewController.class]) { 
      UIViewController* vc = (UIViewController*)view.nextResponder; 
      [vc presentViewController:alertController animated:YES completion:nil]; 
     } 

가 적절한 솔루션인가요? UIAlertController가있는 UIViewController에 추가해야하지만 만에 UIView의 포인터를 얻을 수 있습니다, 그래서 나는 내가 원하는 것을 얻을 view.nextResponder을 사용하지만, 그것은 좋은 것이있다 :

내가 주로 우려에 대해 무엇인가 방법?

답변

63

나는 UIAlertViewController를 사용하여 액션 시트를 보여주기 위해 다음 코드를 사용하고 그것을 완벽하게 작동합니다.

- (IBAction)buttonClicked:(id)sender { 

    UIAlertController *actionSheet = [UIAlertController alertControllerWithTitle:@"Action Sheet" message:@"Using the alert controller" preferredStyle:UIAlertControllerStyleActionSheet]; 

    [actionSheet addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) { 

     // Cancel button tappped. 
     [self dismissViewControllerAnimated:YES completion:^{ 
     }]; 
    }]]; 

    [actionSheet addAction:[UIAlertAction actionWithTitle:@"Delete" style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action) { 

     // Distructive button tapped. 
     [self dismissViewControllerAnimated:YES completion:^{ 
     }]; 
    }]]; 

    [actionSheet addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { 

     // OK button tapped. 

     [self dismissViewControllerAnimated:YES completion:^{ 
     }]; 
    }]]; 

    // Present action sheet. 
    [self presentViewController:actionSheet animated:YES completion:nil]; 
} 

편집 :

현재 UIViewController 개체를 얻을 필요가있다. 전역 변수를 설정하거나 대리자 메소드를 호출하거나 통지를 사용하여이 코드에서보기 컨트롤러 객체를 가져올 수 있습니다.

위의 코드는 위의 코드와 같습니다.

[self.viewController presentViewController:actionSheet animated:YES completion:nil]; 

self.viewController은 실제로이보기를 얻기 전에 설정되는 전역 변수입니다.

이제 다음은 접근 방식이 view.nextResponder를 사용하기 때문에. 나는 그것이 작동하지 않을지도 모른다 두려워한다.

+0

약간의 차이점을 제외하면 거의 동일합니다. 대신 UIViewController의 포인터를 직접 가져올 수 없으므로 대신 UIView.nextResponder를 사용자에게 알리고 싶습니다. –

+0

코드에서'view' 란 무엇입니까? View Controller의 하위보기입니까? – Kampai

+0

실제로 WebView는 phonegap과 같은 콤보 상자를 팝업으로 사용합니다. –

1

대신 view.window.rootViewController을 사용할 수 있습니다. 발표자가 마음에 들지 않으면 괜찮습니다.

25

프로필 사진을 변경하기 위해 작업 시트를 사용했습니다. 난 그냥 취소 또는 사진 선택보기를 눌러 때 뷰의 나를 발로 이후 dismissviewController 호출을 제거 Kampai 접근 방식을, 다음

UIAlertController *actionSheet = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet]; 

[actionSheet addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) { 

    // Cancel button tappped do nothing. 

}]]; 

[actionSheet addAction:[UIAlertAction actionWithTitle:@"Take photo" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { 

    // take photo button tapped. 
    [self takePhoto]; 

}]]; 

[actionSheet addAction:[UIAlertAction actionWithTitle:@"Choose photo" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { 

    // choose photo button tapped. 
    [self choosePhoto]; 

}]]; 

[actionSheet addAction:[UIAlertAction actionWithTitle:@"Delete Photo" style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action) { 

    // Distructive button tapped. 
    [self deletePhoto]; 

}]]; 
10

스위프트 - 업데이트가 매우 간단 보일 수 있지만

let actionSheet = UIAlertController.init(title: "Please choose a source type", message: nil, preferredStyle: .actionSheet) 
    actionSheet.addAction(UIAlertAction.init(title: "Take Photo", style: UIAlertActionStyle.default, handler: { (action) in 
     self.openCamera() 
    })) 
    actionSheet.addAction(UIAlertAction.init(title: "Choose Photo", style: UIAlertActionStyle.default, handler: { (action) in 
     self.showPhotoLibrary() 
    })) 
    actionSheet.addAction(UIAlertAction.init(title: "Cancel", style: UIAlertActionStyle.cancel, handler: { (action) in 
     // self.dismissViewControllerAnimated(true, completion: nil) is not needed, this is handled automatically, 
     //Plus whatever method you define here, gets called, 
     //If you tap outside the UIAlertController action buttons area, then also this handler gets called. 
    })) 
    //Present the controller 
    self.present(actionSheet, animated: true, completion: nil) 
0

UIAlertController를 사용하는 것에 대한 불쾌한 문제입니다. 메모리 누출이 발생하기 쉽습니다. 문제가 발생했는지 테스트하려면 뷰 컨트롤러의 "dealloc"메서드에 중단 점을 놓고 해당 컨트롤러의 할당이 제대로 해제되었는지 확인하십시오.

나는 꽤 오랜 시간 동안 해결책을 찾고 있었는데, 여기에 내 응용 프로그램에서 경고 컨트롤러를 사용하는 방법입니다.

+ (void)alertWithPresenting:(UIViewController *)presenting title:(NSString *)title 
         text:(NSString *)text buttons:(NSArray *)buttons 
        handler:(void (^)(UIAlertAction *action, NSUInteger index))handler 
{ 
     UIAlertController *alert = [UIAlertController 
            alertControllerWithTitle:title message:text 
            preferredStyle:UIAlertControllerStyleAlert]; 
     __weak __typeof(alert) weakAlert = alert; 
     for (NSString *title in buttons) { 
       UIAlertActionStyle style = UIAlertActionStyleDefault; 
       if ([title isEqualToString:[L10n cancelButton]]) 
         style = UIAlertActionStyleCancel; 
       else if ([title isEqualToString:[L10n deleteButton]]) 
         style = UIAlertActionStyleDestructive; 
       else if ([title isEqualToString:[L10n archiveButton]]) 
         style = UIAlertActionStyleDestructive; 

       UIAlertAction *action = [UIAlertAction actionWithTitle:title style:style handler:^(UIAlertAction *action) { 
         if (handler != nil) 
           handler(action, [buttons indexOfObject:action.title]); 
         [weakAlert dismissViewControllerAnimated:YES completion:nil]; 
       }]; 
       [alert addAction:action]; 
     } 
     [presenting presentViewController:alert animated:YES completion:nil]; 
} 

이것은 전부는 아닙니다. 다음은보기 컨트롤러에서이를 사용하는 방법의 예입니다. 필자의 경우 검색을 통한 테이블 뷰이므로 제어기를 제시하는 것이 다를 수 있습니다.

- (void) deleteCases:(NSArray *)selectedRows 
{ 
     NSString *text = NSLocalizedStringWithDefaultValue(@"cases.delete.alert.text", 
                  @"Localizable", [NSBundle mainBundle], 
                  @"Deleted cases cannot be restored. Continue with delete?", 
                  @"Delete alert text"); 
     NSString *title = NSLocalizedStringWithDefaultValue(@"cases.delete.alert.title", 
                  @"Localizable", [NSBundle mainBundle], 
                  @"Delete cases", @"Detete alert title"); 
     UIViewController *presenting = self.searchController.active ? self.searchController : self; 
     __weak __typeof(presenting) weakPresenting = presenting; 
     __weak __typeof(self) weakSelf = self; 
     [YourClassName alertWithPresenting:weakPresenting title:title text:text 
            buttons:@[[L10n deleteButton], [L10n cancelButton]] 
            handler:^(UIAlertAction *action, NSUInteger index) 
     { 
       if (action.style == UIAlertActionStyleDestructive) { 
         __typeof(weakSelf) strongSelf = weakSelf; 
         // Perform your actions using @strongSelf 
       } 
     }]; 
} 
관련 문제