我试图使用自定义UIPopoverPresentationController类来显示弹出窗口。但它崩溃了错误(<UIPopoverPresentationController: 0x7a772950>) should have a non-nil sourceView or barButtonItem set before the presentation occurs.
下面是我发生崩溃的按钮点击代码。
- (IBAction)showPopup:(UIButton *)sender {
ViewController *contentViewController = [[ViewController alloc] init];
contentViewController.preferredContentSize = CGSizeMake(200, 200);
contentViewController.modalPresentationStyle = UIModalPresentationPopover;
myPopoverController *popOver = [[myPopoverController alloc]initWithPresentedViewController:contentViewController presentingViewController:self andTintColor:[UIColor lightGrayColor]];
popOver.delegate = self;
popOver.permittedArrowDirections = UIPopoverArrowDirectionUp;
popOver.sourceRect = sender.frame;
popOver.sourceView = self.view;
[self presentViewController:contentViewController animated: YES completion: nil];
}
以下是我的自定义UIPopoverPresentationController的样子
的示例myPopoverController.h file
@interface myPopoverController : UIPopoverPresentationController
@property (readonly) UIColor *tintColor;
-(instancetype)initWithPresentedViewController:(UIViewController *)presentedViewController presentingViewController:(UIViewController *)presentingViewController andTintColor:(UIColor *)aTintColor;
@end
myPopoverController.m file
//Some code for UIPopoverBackgroundView
-(instancetype)initWithPresentedViewController:(UIViewController *)presentedViewController presentingViewController:(UIViewController *)presentingViewController
{
self = [self initWithPresentedViewController:presentedViewController presentingViewController:presentingViewController andTintColor: [UIColor redColor]];
return self;
}
-(instancetype)initWithPresentedViewController:(UIViewController *)presentedViewController presentingViewController:(UIViewController *)presentingViewController andTintColor:(UIColor *)aTintColor
{
self = [super initWithPresentedViewController:presentedViewController presentingViewController:presentingViewController];
if (!self) {
return nil;
}
[super setPopoverBackgroundViewClass: [myPopoverControllerBackgroundView class]];
tintColor = aTintColor;
return self;
}
我没有按钮但是我设置了sourceView。我在这里做错了吗?感谢您的帮助
答案 0 :(得分:7)
您也可以像这样创建一个弹出式演示控制器,它可以工作
- (IBAction)showPopup:(UIButton *)sender {
ViewController *contentViewController = [[ViewController alloc] init];
contentViewController.preferredContentSize = CGSizeMake(200, 200);
contentViewController.modalPresentationStyle = UIModalPresentationPopover;
UIPopoverPresentationController *popoverpresentationController = contentViewController.popoverPresentationController;
popoverpresentationController.delegate = self;
popoverpresentationController.permittedArrowDirections = UIPopoverArrowDirectionUp;
popoverpresentationController.sourceRect = sender.bounds;
popoverpresentationController.sourceView = sender;
[self presentViewController:contentViewController animated: YES completion: nil];
}
答案 1 :(得分:2)
您正在继承UIPopoverPresentationController
,但Apple recommends将它们原样使用。提交UIViewController
后,系统会自动创建UIPopoverPresentationController
,您应该根据需要对其进行修改。
您创建了一个myPopoverController
个实例,但Apple会在您present
后contentViewController
创建另一个实例:
[self presentViewController:contentViewController animated: YES completion: nil];
这个新UIPopoverPresentationController
缺少sourceView
并抛出异常。
请尝试以下代码:
ViewController *contentViewController = [[ViewController alloc] init];
// Present the view controller using the popover style.
contentViewController.modalPresentationStyle = UIModalPresentationPopover;
[self presentViewController:contentViewController
animated:YES
completion:nil];
// Get the popover presentation controller and configure it.
UIPopoverPresentationController *presentationController =[contentViewController popoverPresentationController];
presentationController.permittedArrowDirections = UIPopoverArrowDirectionUp;
presentationController.sourceView = sender.frame;
presentationController.sourceRect = self.view;
答案 2 :(得分:2)
如果 sourceView 为 null,只需添加验证
UIActivityViewController * avc = [[UIActivityViewController alloc] initWithActivityItems:shareItems applicationActivities:nil];
if(avc.popoverPresentationController){
avc.popoverPresentationController.sourceView = self.view;
}
[self presentViewController:avc animated:YES completion:nil];
答案 3 :(得分:0)
可能低于代码可能有所帮助:
在iPad
中,视图控制器将使用新的UIPopoverPresentationController
显示为弹出窗口,它需要使用以下三个属性之一指定弹出窗口的锚点:
barButtonItem
sourceView
sourceRect
请执行以下操作:
//for iPhone
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
[self presentViewController:controller animated:YES completion:nil];
}
//for iPad
else {
// Change Rect as required
ViewController *contentViewController = [[ViewController alloc] init];
contentViewController.preferredContentSize = CGSizeMake(200, 200);
contentViewController.modalPresentationStyle = UIModalPresentationPopover;
[self presentViewController:contentViewController animated:YES completion:nil];
}
答案 4 :(得分:0)
我认为最好的方法是覆盖当前方法
extension XXXBaseViewController: UIPopoverPresentationControllerDelegate {
override func present(_ viewControllerToPresent: UIViewController, animated flag: Bool, completion: (() -> Void)? = nil) {
if let popController = viewControllerToPresent.popoverPresentationController,
popController.sourceView == nil{
return
}
super.present(viewControllerToPresent, animated: flag, completion: completion)
}
}