Метод setContentViewController в popover iOS8 вызывает сбой приложения
Метод setContentViewController в UIPopoverController, похоже, вызывает крушение приложения в iOS 8. Просто интересно, сталкивался ли кто-либо с этой проблемой в iOS 8. Это работает без каких-либо проблем в iOS 7.
Ошибка, указанная в исключении, кажется, вводит в заблуждение, поскольку она заявляет, что setContentViewController должен быть вызван после представления popover
- (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
Ответы
Ответ 1
Я просто столкнулся с той же ошибкой, протестировавшей наше приложение под iOS 8. В нашем случае я принял сообщение об ошибке по номиналу и изменил шаблон, который у нас был в нескольких местах.
Образец, который нам пришлось изменить, был:
(1) в нашем представлении контроллер init, создайте экземпляр экземпляра popover controller.
(2) на каком-либо событии, установите свойство contentViewController контроллера popover для желаемого vc.
(3) вызов presentPopoverFromRect на контроллере popover
и мы просто изменили шаг (2), чтобы повторно создать контроллер popover с нужным содержимым vc в качестве параметра init и прекратить настройку свойства contentViewController (как это всегда делается перед представлением popover).
Ответ 2
Я пережил эту же проблему и, наконец, решил ее.
У меня есть две кнопки, каждая из которых показывает свой собственный 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];
Ответ 3
Аналогично решению @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;
}
Проблема возникает при переназначении контроллера вида на существующий popover.
Free и realloc popover перед назначением нового контроллера представления содержимого: это исправлено для меня.
Ответ 4
У меня была одна и та же проблема, и это было исправлено для меня.
Попробуйте это
- (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];
}
}
Ответ 5
Добавьте эти два метода в основной класс UIwebview.
добавьте <UIPopoverPresentationControllerDelegate>
в свой класс webview interface.h.
определить.
@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;
}
Ответ 6
У вас уже установлен контроллер содержимого:
_popover = [[UIPopoverController alloc] initWithContentViewController:tableViewController];
↑
Here
Итак, почему бы просто не удалить строку?:
[_popover setContentViewController:tableViewController];
Это должно работать.
Ответ 7
Если popover не отображается, когда вы вызываете [_popover setContentViewController:tableViewController];
, приложение получит сбой.
Поскольку этот метод следует вызывать, когда popover отображается на экране.
Убедитесь, что ваш popover виден,
if(_popover != nil && [_popover isPopoverVisible] == YES)
{
[_popover setContentViewController:tableViewController];
}else
{
//create new popover object if _popover is nil or present it
}
Ответ 8
[self.popover dismissPopoverAnimated:YES]; //in case it 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];
Ответ 9
Вам не нужно создавать новый экземпляр UIPopoverController и не устанавливать новое свойство contentViewController после первого представления UIPopoverViewController. (это зависит от того, как вы уволяете вас popoverController)
Однако contentViewController не может быть изменен перед представлением popoverController.
Чтобы обходным способом проверить свойства popoverController.contentViewController. Если это nil, установите conntentViewController, иначе просто введите popover.
Если вы хотите изменить contentViewController сделать это после представления: используйте метод setContentViewController: анимированный:.
Перед вызовом этого метода убедитесь, что popoverController.isPopoverVisible.