iOS8:不显示 UIPopoverController 但 iOS7 可以

Posted

技术标签:

【中文标题】iOS8:不显示 UIPopoverController 但 iOS7 可以【英文标题】:iOS8: Not show UIPopoverController but iOS7 is OK 【发布时间】:2015-01-21 07:40:59 【问题描述】:

Apple似乎从ios8开始改变了对UIPopoverController的态度。

请看下面的代码。我想在 addSubview 之后显示 UIPopoverController。 iOS6和iOS7没问题,但在iOS8上不显示。

您能提出任何可能的原因吗?任何帮助将不胜感激。

- (IBAction)tapButton:(id)sender 

    SampleView *sampleView = [[SampleView alloc] initWithFrame:CGRectMake(0.0f, 0.0f,
                                                                          [UIScreen mainScreen].bounds.size.width,
                                                                          [UIScreen mainScreen].bounds.size.height)];
    sampleView.backgroundColor = [UIColor blueColor];
    sampleView.alpha = 0.5;

    sampleView.label = [[UILabel alloc] initWithFrame:CGRectMake([UIScreen mainScreen].bounds.size.width / 2,
                                                                 [UIScreen mainScreen].bounds.size.height / 2,
                                                                 200.0f, 20.0f)];
    sampleView.label.text = @"SAMPLE TEXT";
    sampleView.label.textColor = [UIColor redColor];
    [sampleView addSubview:sampleView.label];

    [self.view.window addSubview:sampleView];

    if (!self.popover) 
        UIViewController *vc = [[UIViewController alloc] init];
        vc.view.backgroundColor = [UIColor redColor];
        vc.preferredContentSize = CGSizeMake(200, 300);
        self.popover = [[UIPopoverController alloc] initWithContentViewController:vc];
    

    // On iOS7 is OK but not show on iOS8
    [self.popover presentPopoverFromRect:CGRectMake(200, 100, 0, 0)
                                  inView:sampleView.label
                permittedArrowDirections:UIPopoverArrowDirectionUp
                                animated:YES];

更新1:

我跟着这个问题的答案。

in iOS8: UIPopoverController presentPopoverFromRect not work for keyWindow any more

这是更新的代码。

[self.popover presentPopoverFromRect:CGRectMake(200, 100, 0, 0)
                                  inView:self.view
                permittedArrowDirections:UIPopoverArrowDirectionUp
                                animated:YES];

据我检查,keyWindos 和 self.view.window 似乎是一样的。

NSLog(@"%@", [UIApplication sharedApplication].keyWindow);
NSLog(@"%@", self.view.window);

但是,对于我的情况,这不是完整的解决方案。我想控制添加的子视图的视图。

更新2:

我想我需要在 iOS8 上使用 UIPopoverPresentationController。

- (IBAction)tapButton:(id)sender 

    // View
    SampleView *sampleView = [[SampleView alloc] initWithFrame:CGRectMake(0.0f, 0.0f,
                                                                          [UIScreen mainScreen].bounds.size.width,
                                                                          [UIScreen mainScreen].bounds.size.height)];
    sampleView.backgroundColor = [UIColor blueColor];
    sampleView.alpha = 0.5;

    // Label
    sampleView.label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 200.0f, 20.0f)];
    sampleView.label.text = @"SAMPLE TEXT";
    sampleView.label.textColor = [UIColor redColor];
    [sampleView addSubview:sampleView.label];

    // View Controller
    UIViewController *viewController = [[UIViewController alloc] init];
    viewController.modalPresentationStyle = UIModalPresentationPopover;
    viewController.view = sampleView;

    // UIPopoverPresentationController
    UIPopoverPresentationController *presentationController = viewController.popoverPresentationController;
    [presentationController setDelegate:self];
    presentationController.permittedArrowDirections = 0;
    presentationController.sourceView = [[UIApplication sharedApplication] keyWindow];
    presentationController.sourceRect = [[UIApplication sharedApplication] keyWindow].bounds;

    [viewController setPreferredContentSize:CGSizeMake(320, 480)];
    [self presentViewController:viewController animated:YES completion:nil];

    if (!self.popover) 
        UIViewController *vc = [[UIViewController alloc] init];
        vc.view.backgroundColor = [UIColor redColor];
        vc.preferredContentSize = CGSizeMake(200, 300);
        vc.modalPresentationStyle = UIModalPresentationPopover;
        self.popover = [[UIPopoverController alloc] initWithContentViewController:vc];
        self.popover.delegate = self;
    

    [self.popover presentPopoverFromRect:CGRectMake(300, 300, 0, 0)
                                  inView:viewController.view
                permittedArrowDirections:UIPopoverArrowDirectionUp
                                animated:YES];

Update3 我使用了 dispatch_async 但没用。有人说 dispatch_async 在这种情况下是有效的。 dispatch_async 是非常简单的解决方案。我更喜欢使用它。如果您可以使用 dispatch_async 解决我的问题,我将不胜感激您能附上代码。

- (IBAction)tapButton:(id)sender 

    SampleView *sampleView = [[SampleView alloc] initWithFrame:CGRectMake(0.0f, 0.0f,
                                                                          [UIScreen mainScreen].bounds.size.width,
                                                                          [UIScreen mainScreen].bounds.size.height)];
    sampleView.backgroundColor = [UIColor blueColor];
    sampleView.alpha = 0.5;

    sampleView.label = [[UILabel alloc] initWithFrame:CGRectMake([UIScreen mainScreen].bounds.size.width / 2,
                                                                 [UIScreen mainScreen].bounds.size.height / 2,
                                                                 200.0f, 20.0f)];
    sampleView.label.text = @"SAMPLE TEXT";
    sampleView.label.textColor = [UIColor redColor];
    [sampleView addSubview:sampleView.label];

    [self.view.window addSubview:sampleView];

    if (!self.popover) 
        UIViewController *vc = [[UIViewController alloc] init];
        vc.view.backgroundColor = [UIColor redColor];
        vc.preferredContentSize = CGSizeMake(200, 300);
        self.popover = [[UIPopoverController alloc] initWithContentViewController:vc];
    

    // I tried this but not worked.
    dispatch_async(dispatch_get_main_queue(), ^
        [self.popover presentPopoverFromRect:CGRectMake(200, 100, 0, 0)
                                      inView:sampleView.label
                    permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
    );

【问题讨论】:

【参考方案1】:

为 iOS 8 尝试并执行以下操作

dispatch_async(dispatch_get_main_queue(), ^ [self.popover presentPopoverFromRect:CGRectMake(200, 100, 0, 0) inView:sampleView.label allowedArrowDirections:UIPopoverArrowDirectionUp 动画:YES]; );

编辑

这是我的代码,不管有没有 dispatch_async 都可以。

self.popover = [[UIPopoverController alloc] initWithContentViewController:[self.storyboard instantiateViewControllerWithIdentifier:@"second"]]; dispatch_async(dispatch_get_main_queue(), ^ [self.popover presentPopoverFromRect:self.button.frame inView:self.button allowedArrowDirections:UIPopoverArrowDirectionUp 动画:YES]; );

【讨论】:

谢谢。我试过但没有奏效。请参阅我的问题的 Update3。有人说 dispatch_async 有效,但对我来说不起作用。

以上是关于iOS8:不显示 UIPopoverController 但 iOS7 可以的主要内容,如果未能解决你的问题,请参考以下文章

ios8不显示键盘

Swift/iOS8:为啥不显示页面控制指示器?

iOS8 自定义键盘 Settings.bundle 不显示

iOS 7 uitabbar 显示,在 ios8 上不可见

CALayer 不显示 iOS8

为啥我的 iOS8 应用程序操作扩展应用程序图标不显示?