UIPopoverController中的setContentViewController方法似乎导致iOS 8中的应用程序崩溃。只是想知道是否还有其他人在iOS 8中遇到此问题。这在iOS 7中没有任何问题。
异常中指出的错误似乎有误导性,因为它声明应该在呈现popover之后调用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
答案 0 :(得分:4)
我刚刚在iOS 8下测试了我们的应用程序时遇到同样的错误。在我们的例子中,我在面值处获取了错误消息并更改了我们在几个地方的模式。
我们必须改变的模式是: (1)在我们的视图控制器的init中,实例化一个弹出控制器实例。 (2)在某些事件中,将popover控制器的contentViewController属性设置为所需的vc。 (3)在弹出控制器上调用presentPopoverFromRect
我们只需更改步骤(2)以使用所需内容vc作为init参数重新实例化弹出控制器,并停止设置contentViewController属性(因为我们在呈现弹出窗口之前始终执行此操作)。
答案 1 :(得分:3)
我遇到了同样的问题并最终解决了它。
我有两个按钮,每个按钮都显示自己的弹出窗口。我重复使用相同的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];
答案 2 :(得分:2)
与@ 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;
}
将视图控制器重新分配给现有的弹出窗口时问题会出现。 在分配新的内容视图控制器之前,自由和重新分配弹出窗口:这对我来说是固定的。
答案 3 :(得分:0)
我遇到了同样的问题,这就是为我解决的问题。
试试这个
- (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];
}
}
答案 4 :(得分:0)
将这两个方法添加到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;
}
答案 5 :(得分:0)
您已经设置了内容视图控制器:
_popover = [[UIPopoverController alloc] initWithContentViewController:tableViewController];
↑
Here
那么,为什么不删除该行?:
[_popover setContentViewController:tableViewController];
这应该有效。
答案 6 :(得分:0)
如果在调用[_popover setContentViewController:tableViewController];
时看不到popover,则app会崩溃。
因为当屏幕上显示popover时应该调用此方法。
确保您的弹出窗口可见
if(_popover != nil && [_popover isPopoverVisible] == YES)
{
[_popover setContentViewController:tableViewController];
}else
{
//create new popover object if _popover is nil or present it
}
答案 7 :(得分:0)
[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];
答案 8 :(得分:0)
首次出现 UIPopoverViewController后,您不需要创建 UIPopoverController 的新实例,也不需要设置新的 contentViewController 属性。(取决于具体方法)你解雇了你popoverController)
但是,在popoverController演示之前无法更改 contentViewController 。
要解决此问题,请检查 popoverController.contentViewController 属性。如果 nil ,请设置 conntentViewController ,否则只显示popover。
如果要更改 contentViewController ,请在演示后执行:使用 setContentViewController:animated:方法。 在调用此方法之前,请检查 popoverController.isPopoverVisible 。