我已经阅读了大量关于这个特定主题的 SO 帖子——似乎有很多人在使用带有 UIScrollView 和 UIImageView 的 Autolayout 时遇到问题。或者也许只是有大量的人(比如我自己!)正在阅读教程的 iOS 开发新手碰巧使用这两个对象作为示例。无论如何,虽然我猜测我的问题在某种程度上与这些其他帖子有关,但我的问题是不同的,因为我已经能够完全按照我的意愿使用这些具有自动布局的对象,直到我尝试使用块/线程!
我对自动布局和控制器生命周期的理解是,viewDidLayoutSubviews
当自动布局完成“确定”页面上的内容应该放置的位置时,会调用一个“事件”。我正在/正在使用它对 UIImageView 的zoomScale
属性进行一些计算以缩放图像,使其适合 UISCrollView 提供的空间宽度。
- (void) viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
CGRect scrollViewBounds = self.scrollView.bounds;
CGFloat scrollAspectRatio = scrollViewBounds.size.width/scrollViewBounds.size.height;
CGSize imageViewSize = self.imageView.image.size;
CGFloat imageAspectRatio = imageViewSize.width/imageViewSize.height;
if(imageAspectRatio < scrollAspectRatio){
self.scrollView.zoomScale = scrollViewBounds.size.height/imageViewSize.height;
}else{
self.scrollView.zoomScale = scrollViewBounds.size.width/imageViewSize.width;
}
}
这段代码运行得非常好,直到我开始在不同的线程中加载图像数据(见下文)。现在,我的猜测是,因为我正在异步调用它,所以viewDidLayoutSubviews
在我的图像数据实际返回之前或在它完全加载之前被触发/调用。
//This is called by an external controller and is what "kicks off" the entire process
- (void) setImageURL:(NSURL *)imageURL
{
_imageURL = imageURL;
[self setupImage];
}
//Required for zooming
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return self.imageView;
}
//Here is where the threading/block logic comes in play. If I literally just comment
//out the block/threading related code, everything works perfectly, other then the
//image loading "blocking" the interface
- (void) setupImage
{
if(self.imageView){
self.scrollView.contentSize = CGSizeZero;
self.imageView.image = nil;
NSURL *imageURL = self.imageURL;
dispatch_queue_t imageFetchQ = dispatch_queue_create("image fetcher", NULL);
dispatch_async(imageFetchQ, ^{
NSData *imageData = [[NSData alloc]initWithContentsOfURL:self.imageURL];
UIImage *image = [[UIImage alloc] initWithData:imageData];
if(self.imageURL == imageURL){
if(image){
dispatch_async(dispatch_get_main_queue(), ^{
self.scrollView.contentSize = image.size;
self.imageView.image = image;
self.imageView.frame = CGRectMake(0,0, image.size.width, image.size.height);
});
}
}
});
}
}
我的猜测是我应该监听不同的回调(不确定回调是否是正确的术语),或者我只需要以某种方式“等待”一段时间来强制我的setupImage
逻辑运行(即等待任意时间,希望自动布局完成它并为 UIScrollView 和 UIImageView 的边界分配适当的值等)。
如果它有帮助,可以在此处找到此代码的运行版本:https ://github.com/develpr/PhotoViewr/tree/assignment-5 (请注意,如果您实际下载此代码,则需要输入FlickrAPIKey.h 文件中的 Flickr API 密钥以使其正常工作)。