UIPopoverController出现在iOS 8.1下的不可预知的延迟 [英] Unpredictable delay before UIPopoverController appears under iOS 8.1

查看:87
本文介绍了UIPopoverController出现在iOS 8.1下的不可预知的延迟的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在iOS 8.1下运行时,SDK 8.1会出现此问题,而在iOS 7下运行时则不会出现此问题。仅适用于iPad。模拟器和硬件设备上都会出现问题。

This problem happens with SDK 8.1, when running under iOS 8.1, but not when running under iOS 7. It is for iPad only. The problem appears both with simulator and on a hardware device.

下面的代码演示了一个视图控制器,它包含一行UITableView,下面是一行UIButton。点击按钮或行将导致弹出窗口出现。点击按钮时这很好用,但是当点击表视图的行时,弹出窗口会有一些延迟。在我的测试中,我第一次点击行时弹出窗口通常会出现很少或没有延迟,但是第二次点击行时,弹出窗口出现之前可能需要几秒钟,而且通常直到我点击其他地方才出现风景。然而,即使在行上的第一次敲击时也会发生延迟(特别是在硬件上进行测试时)。

The code below demonstrates a view controller that contains a UITableView with 1 row, and below that, a UIButton. Tapping on the button or on the row will cause a popover to appear. This works just fine when tapping the button, but when tapping the row of the tableview, the popover appears with some delay. In my testing, first time I tap the row the popover usually appears with little or no delay, but second time I tap the row, it can take many seconds before the popover appears, and often it does not appear until I tap somewhere else on the view. However, the delay can happen even at the first tap on the row (especially when tested on hardware).

我展示的代码尽可能地被煮沸,同时保留问题。在我看来,UITableView在某种程度上是导致这种延迟发生的关键。

The code I show has been boiled down as much as possible, while retaining the problem. It seems to me, that the UITableView is somehow critical to cause this delay to happen.

我知道在iOS 8下不推荐使用某些UIPopoverController代码。我有试图在iOS 8上使用UIPopoverPresentationController,结果是一样的:在弹出窗口出现之前有时很长的延迟。我对这种新方法还不是很熟悉,所以我可能会犯错误,但无论如何都可以通过将USE_TRADITIONAL_METHOD宏设置为0而不是1来测试iOS 8代码。

I do know that some of the UIPopoverController code is deprecated under iOS 8. I have tried to use UIPopoverPresentationController for iOS 8, and the result is the same: A sometimes very long delay before the popover appears. I am not yet very familiar with this new approach, so I may well be making mistakes, but in any case the iOS 8 code can be tested by setting the USE_TRADITIONAL_METHOD macro to 0 instead of 1.

我们非常感谢任何有关如何修复或绕过此问题的建议(同时仍使用tableview)。

Any suggestions on how to fix or bypass this (while still using a tableview) will be greatly appreciated.

#import "MyViewController.h"

@interface MyViewController ()

@property (nonatomic) UIPopoverController* myPopoverController;

@end

@implementation MyViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    // setup table view
     UITableView* tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 500, 500) style:UITableViewStyleGrouped];
    [self.view addSubview:tableView];
    tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
    tableView.dataSource = self;
    tableView.delegate = self;
    
    // setup button
    UIButton* button = [UIButton buttonWithType:UIButtonTypeSystem];
    [self.view addSubview:button];
    button.frame = CGRectMake(20, 550, 100, 20);
    [button setTitle:@"Show popover" forState:UIControlStateNormal];
    [button addTarget:self action:@selector(showPopover:) forControlEvents:UIControlEventTouchUpInside];
}


- (IBAction)showPopover:(id)sender
{
    UIView* senderView = (UIView*)sender;
    
    UIViewController* contentViewController = [[UIViewController alloc] init];
    contentViewController.view.backgroundColor = [UIColor purpleColor];
    
#define USE_TRADITIONAL_METHOD 1

#if USE_TRADITIONAL_METHOD
    self.myPopoverController = [[UIPopoverController alloc] initWithContentViewController:contentViewController];
    [self.myPopoverController presentPopoverFromRect:senderView.frame inView:senderView.superview permittedArrowDirections:UIPopoverArrowDirectionLeft animated:NO];
#else
    contentViewController.modalPresentationStyle = UIModalPresentationPopover;

    [self presentViewController:contentViewController animated:NO completion:^{
        NSLog(@"Present completion");       // As expected, this is executed once the popover is actually displayed (which can take a while)
    }];

    // do configuration *after* call to present, as explained in Apple documentation:
    UIPopoverPresentationController* popoverController = contentViewController.popoverPresentationController;
    popoverController.sourceRect = senderView.frame;
    popoverController.sourceView = senderView;
    popoverController.permittedArrowDirections = UIPopoverArrowDirectionLeft;
    
#endif
    NSLog(@"Popover is visible: %d", self.myPopoverController.isPopoverVisible);    // This shows "1" (visible) for USE_TRADITIONAL_METHOD, under both iOS 7 and iOS 8
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 1;
}

-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
    cell.textLabel.text = @"Show popover";
    return cell;
}

#pragma mark - UITableViewDelegate

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [self showPopover:[tableView cellForRowAtIndexPath:indexPath]];
}


@end

推荐答案

我发现在尝试显示之前取消选择该行popover似乎解决了这个问题。这可能是一个有用的解决方法,但我仍然在寻找更好的答案,因为这可能不是很强大。

I found that deselecting the row before attempting to show the popover seems to fix the problem. This may be a useful work-around, but I'm still looking for a better answer, since this may not be robust.

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView deselectRowAtIndexPath:indexPath animated:NO]; // adding this line appears to fix the problem
    [self showPopover:[tableView cellForRowAtIndexPath:indexPath]];
}

这篇关于UIPopoverController出现在iOS 8.1下的不可预知的延迟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆