簡體   English   中英

popover iOS8中的setContentViewController方法導致應用程序崩潰

[英]setContentViewController method in popover iOS8 causes app crash

UIPopoverController中的setContentViewController方法似乎導致iOS 8中的應用程序崩潰。只是想知道是否還有其他人在iOS 8中遇到此問題。這在iOS 7中沒有任何問題。

異常中指出的錯誤似乎是誤導性的,因為它聲明應該在呈現彈出窗口后調用setContentViewController

- (void)buttonPressed {

UIViewController *tableViewController = [UIViewController new];

if(_popover == nil){

    _popover = [[UIPopoverController alloc] initWithContentViewController:tableViewController];

    [_popover presentPopoverFromRect:CGRectMake(self.textField.frame.size.width / 2, self.textField.frame.size.height / 1, 1, 1) inView:self.textField permittedArrowDirections:UIPopoverArrowDirectionLeft animated:YES];
}else{
    [_popover setContentViewController:tableViewController];
}    

}

這是崩潰的堆棧跟蹤,

2014-09-11 16:48:39.904 iOS 8 Rotation[3969:67869] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIPopoverController setContentViewController:animated:] can only be called after the popover has been presented.'
*** First throw call stack:
(
    0   CoreFoundation                      0x01c79df6 __exceptionPreprocess + 182
    1   libobjc.A.dylib                     0x01903a97 objc_exception_throw + 44
    2   CoreFoundation                      0x01c79d1d +[NSException raise:format:] + 141
    3   UIKit                               0x00b1946f -[UIPopoverPresentationController _setContentViewController:animated:] + 89
    4   UIKit                               0x009bb1b4 -[UIPopoverController setContentViewController:animated:] + 155
    5   UIKit                               0x009bb114 -[UIPopoverController setContentViewController:] + 48
    6   iOS 8 Rotation                      0x00046ca5 -[MianViewController buttonPressed] + 933
    7   libobjc.A.dylib                     0x019197cd -[NSObject performSelector:withObject:withObject:] + 84
    8   UIKit                               0x002ef79d -[UIApplication sendAction:to:from:forEvent:] + 99
    9   UIKit                               0x002ef72f -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 64
    10  UIKit                               0x00422a16 -[UIControl sendAction:to:forEvent:] + 69
    11  UIKit                               0x00422e33 -[UIControl _sendActionsForEvents:withEvent:] + 598
    12  UIKit                               0x0042209d -[UIControl touchesEnded:withEvent:] + 660
    13  UIKit                               0x0033faba -[UIWindow _sendTouchesForEvent:] + 874
    14  UIKit                               0x00340595 -[UIWindow sendEvent:] + 791
    15  UIKit                               0x00305aa9 -[UIApplication sendEvent:] + 242
    16  UIKit                               0x003158de _UIApplicationHandleEventFromQueueEvent + 20690
    17  UIKit                               0x002ea079 _UIApplicationHandleEventQueue + 2206
    18  CoreFoundation                      0x01b9d7bf __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
    19  CoreFoundation                      0x01b932cd __CFRunLoopDoSources0 + 253
    20  CoreFoundation                      0x01b92828 __CFRunLoopRun + 952
    21  CoreFoundation                      0x01b921ab CFRunLoopRunSpecific + 443
    22  CoreFoundation                      0x01b91fdb CFRunLoopRunInMode + 123
    23  GraphicsServices                    0x040cc24f GSEventRunModal + 192
    24  GraphicsServices                    0x040cc08c GSEventRun + 104
    25  UIKit                               0x002ede16 UIApplicationMain + 1526
    26  iOS 8 Rotation                      0x0004774d main + 141
    27  libdyld.dylib                       0x0224cac9 start + 1
    28  ???                                 0x00000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

我剛剛在iOS 8下測試了我們的應用程序時遇到了同樣的錯誤。在我們的例子中,我在面值處獲取了錯誤消息並更改了我們在幾個地方的模式。

我們必須改變的模式是:(1)在我們的視圖控制器的init中,實例化一個彈出控制器實例。 (2)在某些事件中,將popover控制器的contentViewController屬性設置為所需的vc。 (3)在彈出控制器上調用presentPopoverFromRect

我們只需更改步驟(2)以使用所需內容vc作為init參數重新實例化popover控制器並停止設置contentViewController屬性(因為我們在呈現popover之前總是這樣做)。

我遇到了同樣的問題並最終解決了它。

我有兩個按鈕,每個按鈕顯示自己的彈出窗口。 我重復使用相同的UIPopoverController來顯示它們。 第一次點擊工作正常,但如果你點擊另一個點擊應用程序崩潰。

我解決它的方法是在每次點擊時創建一個新的UIPopoverController:

importImagePickerControlPopoverController=[[UIPopoverController alloc] initWithContentViewController:pickerController];
[importImagePickerControlPopoverController setDelegate:self];

switch(pickerType)
{
    case UIImagePickerControllerSourceTypePhotoLibrary:
    case UIImagePickerControllerSourceTypeSavedPhotosAlbum:
        [importImagePickerControlPopoverController setPopoverContentSize:CGSizeMake(320, 300) animated:YES];
        break;
    case UIImagePickerControllerSourceTypeCamera:
        [importImagePickerControlPopoverController setPopoverContentSize:CGSizeMake(640, 640) animated:YES];
        break;
}
[importImagePickerControlPopoverController setContentViewController:pickerController];

與@ user3495742解決方案類似:

-(void)testAndSetPopoverWithVc:(UIViewController*)vc {
    if (popover4Menu) {
        if ([popover4Menu isPopoverVisible]) {
            [popover4Menu setContentViewController:vc animated:YES];
            return;
        } else {
            popover4Menu=nil;
        }
    };
    popover4Menu=[[UIPopoverController alloc] initWithContentViewController:vc];
    popover4Menu.delegate=self;
}

將視圖控制器重新分配給現有的彈出窗口時問題會出現。 在分配新的內容視圖控制器之前自由和realloc popover:這對我來說是固定的。

我遇到了同樣的問題,這就是為我解決的問題。

試試這個

- (void)buttonPressed{

  UIViewController *tableViewController = [UIViewController new];

  //Check if the popover is nil or not visible
  if(_popover == nil || _popover.popoverVisible == false){

    _popover = [[UIPopoverController alloc] initWithContentViewController:tableViewController];

    [_popover presentPopoverFromRect:CGRectMake(self.textField.frame.size.width / 2, self.textField.frame.size.height / 1, 1, 1) inView:self.textField permittedArrowDirections:UIPopoverArrowDirectionLeft animated:YES];
  }else{
    [_popover setContentViewController:tableViewController];
  }
}

將這兩個方法添加到UIwebview主類中。 在webview interface.h類中添加<UIPopoverPresentationControllerDelegate> 定義。

@property (strong, nonatomic) UIPopoverPresentationController *pop;

然后

@synthesize pop;

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Assuming you've hooked this all up in a Storyboard with a popover presentation style
    if ([segue.identifier isEqualToString:@"showPopover"]) {
        UINavigationController *destNav = segue.destinationViewController;
        pop = destNav.viewControllers.firstObject;

        // This is the important part
        UIPopoverPresentationController *popPC = destNav.popoverPresentationController;
        popPC.delegate = self;
    }
}
- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller {
    return UIModalPresentationNone;
}

您已經設置了內容視圖控制器:

_popover = [[UIPopoverController alloc] initWithContentViewController:tableViewController]; 
                                                                        ↑
                                                                      Here

那么,為什么不刪除該行?:

 [_popover setContentViewController:tableViewController];

這應該工作。

如果在調用[_popover setContentViewController:tableViewController];時看[_popover setContentViewController:tableViewController]; ,應用程序將崩潰。

因為當屏幕上顯示popover時應該調用此方法。

確保您的彈出窗口可見,

if(_popover != nil && [_popover isPopoverVisible] == YES)
{
   [_popover setContentViewController:tableViewController];
}else
{
       //create new popover object if _popover is nil or present it
}
   [self.popover dismissPopoverAnimated:YES]; //in case it's already showing.  
   self.popover = nil; // N.B. this is not the same as popover = nil. 
   self.popover = [[UIPopoverController alloc] initWithContentViewController:tableViewController];
   [self.popover  presentPopoverFromRect:CGRectMake(self.textField.frame.size.width /
   2, self.textField.frame.size.height / 1, 1, 1) inView:self.textField
   permittedArrowDirections:UIPopoverArrowDirectionLeft animated:YES];

首次出現UIPopoverViewController后,您不需要創建新的UIPopoverController實例也不需要設置新的contentViewController屬性 (這取決於你如何解雇你popoverController)

但是,在popoverController演示之前無法更改contentViewController

要解決此問題,請檢查popoverController.contentViewController屬性。 如果是nil ,請設置conntentViewController ,否則只顯示popover

如果你想更改contentViewController,請在演示之后執行:使用setContentViewController:animated:方法。 在調用此方法之前檢查popoverController.isPopoverVisible

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM