gpt4 book ai didi

ios - presentViewController :animated:YES view will not appear until user taps again

转载 作者:IT王子 更新时间:2023-10-29 07:30:11 25 4
gpt4 key购买 nike

我在使用 presentViewController:animated:completion 时遇到了一些奇怪的行为。我正在做的基本上是一个猜谜游戏。

我有一个包含 UITableView (frequencyTableView) 的 UIViewController (frequencyViewController)。当用户点击 questionTableView 中包含正确答案的行时,应该实例化一个 View (correctViewController),并且它的 View 应该从屏幕底部向上滑动,作为模态视图。这告诉用户他们有一个正确的答案并重置其背后的 frequencyViewController 为下一个问题做好准备。 correctViewController 在按下按钮时被关闭以显示下一个问题。

这一切每次都正常工作,只要 presentViewController:animated:completionanimated:NO,正确的 ViewController 的 View 就会立即出现。

如果我设置animated:YES,correctViewController 会被初始化并调用viewDidLoad。但是,viewWillAppearviewDidAppearpresentViewController:animated:completion 的完成 block 不会被调用。在我第二次点击之前,该应用程序仍然显示 frequencyViewController。现在,调用 viewWillAppear、viewDidAppear 和完成 block 。

我进行了更多调查,这不仅仅是另一个会导致它继续的水龙头。似乎如果我倾斜或摇动我的 iPhone,这也会导致它触发 viewWillLoad 等。这就像它在等待任何其他用户输入之前会继续进行。这发生在真实的 iPhone 和模拟器中,我通过向模拟器发送摇动命令证明了这一点。

我真的不知道该怎么办......我真的很感激任何人可以提供的帮助。

谢谢

这是我的代码。这很简单...

这是 questionViewController 中的代码,充当 questionTableView 的委托(delegate)

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{

if (indexPath.row != [self.frequencyModel currentFrequencyIndex])
{
// If guess was wrong, then mark the selection as incorrect
NSLog(@"Incorrect Guess: %@", [self.frequencyModel frequencyLabelAtIndex:(int)indexPath.row]);
UITableViewCell *cell = [self.frequencyTableView cellForRowAtIndexPath:indexPath];
[cell setBackgroundColor:[UIColor colorWithRed:240/255.0f green:110/255.0f blue:103/255.0f alpha:1.0f]];
}
else
{
// If guess was correct, show correct view
NSLog(@"Correct Guess: %@", [self.frequencyModel frequencyLabelAtIndex:(int)indexPath.row]);
self.correctViewController = [[HFBCorrectViewController alloc] init];
self.correctViewController.delegate = self;
[self presentViewController:self.correctViewController animated:YES completion:^(void){
NSLog(@"Completed Presenting correctViewController");
[self setUpViewForNextQuestion];
}];
}
}

这是正确的ViewController的全部内容

@implementation HFBCorrectViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
{
// Custom initialization
NSLog(@"[HFBCorrectViewController initWithNibName:bundle:]");
}
return self;
}

- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
NSLog(@"[HFBCorrectViewController viewDidLoad]");
}

- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
NSLog(@"[HFBCorrectViewController viewDidAppear]");
}

- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}

- (IBAction)close:(id)sender
{
NSLog(@"[HFBCorrectViewController close:sender:]");
[self.delegate didDismissCorrectViewController];
}


@end

编辑:

我之前发现了这个问题:UITableView and presentViewController takes 2 clicks to display

如果我将我的 didSelectRow 代码更改为这个,它会在很短的时间内使用动画...但是它很困惑并且没有意义为什么它首先不起作用.所以我不认为这是一个答案...

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{

if (indexPath.row != [self.frequencyModel currentFrequencyIndex])
{
// If guess was wrong, then mark the selection as incorrect
NSLog(@"Incorrect Guess: %@", [self.frequencyModel frequencyLabelAtIndex:(int)indexPath.row]);
UITableViewCell *cell = [self.frequencyTableView cellForRowAtIndexPath:indexPath];
[cell setBackgroundColor:[UIColor colorWithRed:240/255.0f green:110/255.0f blue:103/255.0f alpha:1.0f]];
// [cell setAccessoryType:(UITableViewCellAccessoryType)]

}
else
{
// If guess was correct, show correct view
NSLog(@"Correct Guess: %@", [self.frequencyModel frequencyLabelAtIndex:(int)indexPath.row]);

////////////////////////////
// BELOW HERE ARE THE CHANGES
[self performSelector:@selector(showCorrectViewController:) withObject:nil afterDelay:0];
}
}

-(void)showCorrectViewController:(id)sender
{
self.correctViewController = [[HFBCorrectViewController alloc] init];
self.correctViewController.delegate = self;
self.correctViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentViewController:self.correctViewController animated:YES completion:^(void){
NSLog(@"Completed Presenting correctViewController");
[self setUpViewForNextQuestion];
}];
}

最佳答案

我今天遇到了同样的问题。我深入研究了这个话题,它似乎与主运行循环正在 sleep 有关。

实际上这是一个非常微妙的错误,因为如果您的代码中有最轻微的反馈动画、计时器等,这个问题就不会浮出水面,因为运行循环将由这些来源保持事件状态。我通过使用将其 selectionStyle 设置为 UITableViewCellSelectionStyleNoneUITableViewCell 发现了问题,因此没有选择动画在该行之后触发运行循环选择处理程序运行。

要修复它(直到 Apple 采取措施),您可以通过多种方式触发主运行循环:

侵入性最小的解决方案是调用CFRunLoopWakeUp:

[self presentViewController:vc animated:YES completion:nil];
CFRunLoopWakeUp(CFRunLoopGetCurrent());

或者你可以在主队列中加入一个空 block :

[self presentViewController:vc animated:YES completion:nil];
dispatch_async(dispatch_get_main_queue(), ^{});

这很有趣,但如果您摇动设备,它也会触发主循环(它必须处理运动事件)。与水龙头相同,但这包含在原始问题中:)此外,如果系统更新状态栏(例如时钟更新、WiFi 信号强度变化等),这也会唤醒主循环并呈现 View Controller 。

对于任何感兴趣的人,我写了一个最小的问题演示项目来验证运行循环假设:https://github.com/tzahola/present-bug

我还向 Apple 报告了该错误。

关于ios - presentViewController :animated:YES view will not appear until user taps again,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21075540/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com