Iphone 在iOS中的UI活动期间有条件地(取决于持续时间)显示活动指示器

Iphone 在iOS中的UI活动期间有条件地(取决于持续时间)显示活动指示器,iphone,ios,ipad,uiscrollview,uiactivityindicatorview,Iphone,Ios,Ipad,Uiscrollview,Uiactivityindicatorview,我使用UIScrollView显示PDF文件。水平滚动可更改页面。这很好,但是当下一页是全尺寸图像时,scrollview会在开始设置滚动动画之前停止。这是正常的行为 我希望在持续时间超过(例如)1秒时显示活动指示器,以改进对用户的反馈 我已经尝试过启动计时器的天真方法,计时器在一秒钟后启动指示器。它没有显示,我假设它与需要很长时间的UI活动(更改页面)在同一线程上排队。我还尝试使用performSelectorOnMainThread启动指示器,但这是一个很弱的猜测,没有帮助 我对iOS中线程

我使用UIScrollView显示PDF文件。水平滚动可更改页面。这很好,但是当下一页是全尺寸图像时,scrollview会在开始设置滚动动画之前停止。这是正常的行为

我希望在持续时间超过(例如)1秒时显示活动指示器,以改进对用户的反馈

我已经尝试过启动计时器的天真方法,计时器在一秒钟后启动指示器。它没有显示,我假设它与需要很长时间的UI活动(更改页面)在同一线程上排队。我还尝试使用performSelectorOnMainThread启动指示器,但这是一个很弱的猜测,没有帮助


我对iOS中线程的理解就是这里的问题所在。我只能猜测,我必须中断页面更改,执行活动指示器的开始,然后继续更改(呈现)页面。我不知道怎么做。非常感谢。

我猜您的计时器没有启动,因为在调用
performselectornmainthread
方法或调度
NSTimer
时,您使用的是默认的运行循环模式。它不起作用,因为在这种情况下,滚动完成后,即释放手指后,将调用您的方法

要使计时器即使在滚动期间也能启动,请使用
nsrunlopcommonmodes
作为运行循环模式

[self performSelectorOnMainThread:@selector(yourMethod)
                       withObject:nil
                    waitUntilDone:NO
                            modes:@[NSRunLoopCommonModes]];
编辑

您不应该阻止主线程,否则在主线程完成加载图像之前不会调用该方法。而是在后台线程中加载图像,并通过实现委托方法防止滚动视图滚动

- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
  if([self isLoadingImage]){
    //save the content offset when you start loading the image
    //and use it here to stop scroll view from scrolling.
    scrollView.contentOffset = offsetWhenLoadingStarted;
  }
}

图像的加载可能发生在主线程上,因此它会阻塞您的UI。您应该尝试在与主队列不同的队列上加载,然后显示活动指示器。然后,当图像加载完成后,停止活动指示器并相应地更新滚动视图。没错,图像加载确实发生在主线程上。我只是把它移到后台线程进行测试。不幸的是,这也改变了滚动行为:它现在确实会立即滚动到一个白色页面,并且一旦图像准备好就显示出来。我宁愿采用旧的方式:ScrollView有点僵硬,但当滚动发生时,下一页已经存在了。这样可以避免中间出现令人讨厌的白色闪烁……当“卡住”的时间太长时,我想显示活动指示器。谢谢你的回答。我刚刚尝试了你的建议,但是由于图像加载也是在主线程上完成的,所以计时器事件仍然太晚了。然而,它似乎比以前快了一点。它在scrollview滚动时触发,但在scrollview被卡住时不会触发。谢谢你,我明白了。如果阻塞主线程,则无法实现所需的功能。我已经编辑了答案,并添加了如何在不阻塞主线程的情况下防止滚动视图滚动的方法。这是一种解决方法,但我认为没有更直接的方法。非常感谢。