[英]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.