You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在prepareForSegue调用前启动等待动画并在其完成后关闭?

兄弟,你猜的完全没错!prepareForSegue是在主线程执行的,如果里面有耗时操作(比如数据处理、网络请求或者复杂的模型初始化),会直接把主线程堵死——你的等待动画刚要开始渲染,就被后面的耗时操作卡住了,等所有准备工作做完,动画刚显示出来就被立刻关闭,所以你根本看不到它。

给你一套可行的解决方案,核心思路是把耗时的准备工作移到后台线程,让主线程专注于显示动画和处理UI跳转:

步骤1:修改按钮的触发逻辑

如果你的DoneButton是直接在Storyboard里绑定了Segue(就是从按钮直接拖到下一个控制器),先取消这个绑定,改成给按钮添加点击事件:

- (IBAction)doneButtonTapped:(UIButton *)sender {
    // 第一步:立刻启动等待动画(这时候主线程没被阻塞,动画能正常显示)
    [self startWaitingAnimation];
    
    // 第二步:把耗时的准备工作丢到后台队列执行
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        // 这里放你原本在prepareForSegue里的耗时操作:
        // 比如处理数据、请求接口、初始化复杂模型等等
        // 举个例子,模拟2秒的耗时操作
        [NSThread sleepForTimeInterval:2];
        
        // 第三步:准备工作完成后切回主线程
        dispatch_async(dispatch_get_main_queue(), ^{
            // 先关闭等待动画
            [self stopWaitingAnimation];
            
            // 手动触发Segue跳转
            [self performSegueWithIdentifier:@"YourSegueID" sender:self];
        });
    });
}

步骤2:简化prepareForSegue的逻辑

现在prepareForSegue里只做轻量的UI数据传递,不要再放任何耗时操作:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([segue.identifier isEqualToString:@"YourSegueID"]) {
        NextViewController *nextVC = segue.destinationViewController;
        // 这里只做简单的数据传递,比如把后台处理好的数据传给下一个控制器
        nextVC.processedData = self.myProcessedData;
    }
}

额外注意点

  • 确保你的startWaitingAnimation和stopWaitingAnimation方法里的UI操作都是在主线程执行的(一般UI操作默认都是主线程,只要你没手动把它们丢去后台就没问题)。
  • 如果你的准备工作涉及到网络请求,建议用NSURLSession或者AFNetworking这类自带后台线程处理的框架,避免自己手动管理线程出问题。

这样调整后,等待动画会在点击按钮后立刻显示,后台默默完成准备工作,等一切就绪后关闭动画再跳转,完美解决你的问题!

内容的提问来源于stack exchange,提问作者Reza.Ab

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:56:59