在 UIScrollView 内更新 UIImageView - 滚动时图像冻结

Posted

技术标签:

【中文标题】在 UIScrollView 内更新 UIImageView - 滚动时图像冻结【英文标题】:Updating UIImageView inside UIScrollView - image freezes on scroll 【发布时间】:2012-03-06 17:58:47 【问题描述】:

我在 UIScrollView 中有 UIImageView。 UIImageView 显示不断从互联网下载的图像(使用 NSURLConnection 打开的流)。

NSString surl = @"some valid url";
NSURL* nsurl = [NSURL URLWithString:surl];
NSURLRequest *request = [NSURLRequest requestWithURL:nsurl];
[[NSURLConnection alloc] initWithRequest:request delegate:self];

// this method will be called when every chunk of data is received
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data

    // here I collect data and when i have enough
    // data to create UIImage i create one

每次我收到数据时,我都会将它打包到一个 NSData 中,当我收到整个图像时,我会从这个 NSData 创建 UIImage,然后我将此图像设置为 UIImageView 的图像。一切正常,图像更新正常,但是当我触摸屏幕并开始移动内容时(这个 UIImageView 总是比屏幕大,UIScrollView 总是适合整个屏幕)图像更新停止,我只看到最后一帧显示在我点击的时间。这似乎是因为我的

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data

停止被调用。从屏幕方法释放我的手指后,再次接收数据和图像更新。我不知道为什么我的 NSURLConnection 委托方法停止接收数据。有什么帮助吗?

【问题讨论】:

【参考方案1】:

-[NSURLConnection initWithRequest:didReceiveData:] 的文档是这样说的:

默认情况下,要使连接正常工作,调用线程的运行循环必须在默认运行循环模式下运行。

我假设您正在主线程上创建NSURLConnection

UIScrollView 跟踪触摸时,它会以不同的模式运行运行循环,而不是默认模式。这就是您在触摸滚动视图时停止获取更新的原因。 (这也会导致NSTimers 在您触摸滚动视图时停止触发。)

我认为您可以将NSURLConnection 设置为在默认模式和滚动视图跟踪模式下运行,如下所示:

NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request
    delegate:self startImmediately:NO];
[connection scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode: NSRunLoopCommonModes];
[connection start];

【讨论】:

【参考方案2】:

听起来您的用户交互正在阻止您的数据更新,因为它们都在主线程上运行。我恰好在不久前回复了一对very similar question。

【讨论】:

以上是关于在 UIScrollView 内更新 UIImageView - 滚动时图像冻结的主要内容,如果未能解决你的问题,请参考以下文章

WKWebview & UIImageView 在 UIScrollView 内以编程方式自动布局 Objective-C

UIScrollView 内 UIScrollView 内 UIScrollView

UIScrollView 子视图中滚动事件的锁定处理(在 UIScrollView 超级视图内)

如何在 UICollectionViewCell 内缩放 UIScrollView?

UIView 不会在 UIScrollView 内垂直滚动

UITableView 未显示在 UIScrollView 内