2016-11-23 111 views
0

我正在使用objective-c写入关于UIAlertControllerStyleActionSheetUIAlertcontrolleriOS popover显示两次会崩溃

我想在iPhone上显示警报表,并在iPad上显示popoverPresentationController

首先,我已经设置了UIPopoverPresentationControllerDelegate委托。

当我点击我的按钮时,弹出窗口显示正确。

但我点击屏幕关闭弹出。它会显示下面的警告。

[警告] < _UIPopoverBackgroundVisualEffectView 0x14be52ef0>被要求为其不透明度设置动画。这将导致效果显示中断,直到不透明度返回到1.

现在当我单击按钮时再次显示弹出视图。

它会在日志下面显示崩溃。

由于未捕获的异常“NSGenericException”而终止应用程序,原因:'您的应用程序提供了样式为UIAlertControllerStyleActionSheet的UIAlertController()。具有此样式的UIAlertController的modalPresentationStyle是UIModalPresentationPopover。您必须通过警报控制器的popoverPresentationController为此弹出窗口提供位置信息。您必须提供sourceView和sourceRect或barButtonItem。如果在提供警报控制器时未知此信息,则可以在UIPopoverPresentationControllerDelegate方法-prepareForPopoverPresentation中提供该信息。 ***第一掷调用堆栈: (0x18d9a41c0 0x18c3dc55c 0x19418a8b0 0x193ac60a8 0x193ac3df4 0x193a08d0c 0x1939faac0 0x19376a22c 0x18d9517dc 0x18d94f40c 0x18d94f89c 0x18d87e048 0x18f2ff198 0x1937e2b50 0x1937dd888 0x10011198c 0x18c8605b8) 的libC++ abi.dylib:与类型的未捕获的异常终止NSException

有谁知道如何解决这个问题?

我的代码如下:

@interface ViewController()  <...UITextViewDelegate,UITextFieldDelegate...> { 
     UIAlertController *alertTypeAlertController; 
     UIAlertAction *alertType1Action; 
     UIAlertAction *alertType2Action; 
     UIPopoverPresentationController *popPresenter; 
    } 

- (void)viewDidLoad { 
     [super viewDidLoad]; 


    alertTypeAlertController = [UIAlertController 
          alertControllerWithTitle:@"selecte one:" 
          message:nil 
          preferredStyle:UIAlertControllerStyleActionSheet]; 

alertType1Action = [UIAlertAction 
        actionWithTitle:@"Type1" 
        style:UIAlertActionStyleDefault 
        handler:nil]; 
alertType2Action = [UIAlertAction 
        actionWithTitle:@"Type2" 
        style:UIAlertActionStyleDefault 
        handler:nil]; 
    [alertTypeAlertController addAction: alertType1Action]; 
    [alertTypeAlertController addAction: alertType2Action]; 

    // for ipad 
    popPresenter = [alertTypeAlertController             popoverPresentationController]; 

    popPresenter.permittedArrowDirections = UIPopoverArrowDirectionLeft; 

    popPresenter.delegate = self; 
    popPresenter.sourceView = self.theTypeBtn;      
    popPresenter.sourceRect = CGRectMake(230, 22, 10, 10); 

    .... 
    } 

    - (void)popoverPresentationControllerDidDismissPopover:(UIPopoverPresentationController *)popoverPresentationController { 
// called when a Popover is dismissed 
    } 

    - (BOOL)popoverPresentationControllerShouldDismissPopover:(UIPopoverPresentationController *)popoverPresentationController { 

// return YES if the Popover should be dismissed 
// return NO if the Popover should not be dismissed 
return YES; 
    } 

    -(UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller { 

return UIModalPresentationNone; 
    } 
enter code here 

非常感谢你。

回答

2

也许UIAlertControllerUIPopoverPresentationController对象被ViewController对象强烈引用,这使得Popover无法在释放它后释放该对象 。


后来我发现你的问题是,你尝试在viewDidLoad方法来创建popPresenter 一次,每次你触摸 按钮时出示它,你应该创建一个新的来代替,你可以移动viewDidLoad中代码的新方法,并通过触摸事件调用它,解决这样的:

- (void)makePopover 
{ 
    alertTypeAlertController = [UIAlertController 
           alertControllerWithTitle:@"selecte one:" 
           message:nil 
           preferredStyle:UIAlertControllerStyleActionSheet]; 

    alertType1Action = [UIAlertAction 
         actionWithTitle:@"Type1" 
         style:UIAlertActionStyleDefault 
         handler:nil]; 
    alertType2Action = [UIAlertAction 
         actionWithTitle:@"Type2" 
         style:UIAlertActionStyleDefault 
         handler:nil]; 
    [alertTypeAlertController addAction: alertType1Action]; 
    [alertTypeAlertController addAction: alertType2Action]; 

    // for ipad 
    popPresenter = [alertTypeAlertController             popoverPresentationController]; 

    popPresenter.permittedArrowDirections = UIPopoverArrowDirectionLeft; 
    popPresenter.canOverlapSourceViewRect = YES; // adding this line 
    popPresenter.delegate = self; 
    popPresenter.sourceView = self.theTypeBtn; 
    popPresenter.sourceRect = CGRectMake(230, 22, 10, 10); 
} 
- (IBAction)touchButton:(id)sender { 
    [self makePopover]; 
    [self presentViewController:alertTypeAlertController animated:YES completion:nil]; 
} 
+0

我试试“UIPopoverPresentationController * popPresenter”,结果仍然显示了同样的错误之前添加__weak。:( – dickfala

+0

检查第二个弹出如果self.presentedViewController是零,正常的应用程序崩溃,如果你试图呈现2查看控制器 –

+0

我查看第一个点击按钮,弹出窗口是零(self.presentedViewController),但是显示正确,应用程序没有崩溃,但点击第二个按钮,弹出窗口仍然为零,应用程序崩溃。@@ – dickfala

0

我只是修改代码,请检查其是否工作或没有。

- (IBAction)actionButton:(UIButton*)sender { 
     alertTypeAlertController = [UIAlertController 
          alertControllerWithTitle:@"selecte one:" 
          message:nil 
          preferredStyle:UIAlertControllerStyleActionSheet]; 

     alertType1Action = [UIAlertAction 
        actionWithTitle:@"Type1" 
        style:UIAlertActionStyleDefault 
        handler:nil]; 
     alertType2Action = [UIAlertAction 
        actionWithTitle:@"Type2" 
        style:UIAlertActionStyleDefault 
        handler:nil]; 
     [alertTypeAlertController addAction: alertType1Action]; 
     [alertTypeAlertController addAction: alertType2Action]; 

    // for ipad 
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { 
     popPresenter = [alertTypeAlertController             popoverPresentationController];  
     popPresenter.permittedArrowDirections = UIPopoverArrowDirectionLeft; 

     popPresenter.delegate = self; 
     popPresenter.sourceView = self.theTypeBtn;      
     popPresenter.sourceRect = CGRectMake(230, 22, 10, 10); 
    } 
    [self presentViewController:alertTypeAlertController animated:YES completion:nil]; 
    } 
+0

我试试这个方法,如果我舔按钮,它会崩溃。日志:***终止应用程序,由于未捕获异常'NSInvalidArgumentException',原因:'应用程序试图在目标上呈现一个无模式视图控制器。 – dickfala