SDK 8.1 在 iOS 8.1 下运行时会出现此问题,但在 iOS 7 下运行时不会出现此问题。它仅适用于 iPad。该问题在模拟器和硬件设备上都会出现。
下面的代码演示了一个视图控制器,其中包含一个具有 1 行的 UITableView,其下方是一个 UIButton。点击按钮或行将出现一个弹出窗口。当点击按钮时,效果很好,但是当点击表格视图的行时,弹出窗口会出现一些延迟。在我的测试中,第一次点击该行时,弹出窗口通常会出现很少或没有延迟,但第二次点击该行时,可能需要很多秒才能出现弹出窗口,并且通常直到我点击其他地方后才会出现。风景。但是,即使在第一次点击行时也会发生延迟(尤其是在硬件上测试时)。
我展示的代码已尽可能地简化,同时保留了问题。在我看来, UITableView 在某种程度上对于导致这种延迟发生至关重要。
我确实知道一些 UIPopoverController 代码在 iOS 8 下已被弃用。我尝试在 iOS 8 中使用 UIPopoverPresentationController,结果是相同的:有时在弹出窗口出现之前会出现很长的延迟。我还不太熟悉这种新方法,所以我很可能会犯错误,但无论如何,可以通过将 USE_TRADITIONAL_METHOD 宏设置为 0 而不是 1 来测试 iOS 8 代码。
任何有关如何修复或绕过此问题(同时仍使用表格视图)的建议将不胜感激。
#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
我发现在尝试显示弹出窗口之前取消选择该行似乎可以解决问题。这可能是一个有用的解决方法,但我仍在寻找更好的答案,因为这可能不可靠。
-(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]];
}
请注意,正如 Yasir Ali 评论的那样,要使此解决方法发挥作用,必须关闭取消选择动画。在最初的帖子发布近 4 年之后,这种行为仍然影响 iOS 12,并且 Apple 的错误报告仍然开放 - 叹息。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)