Ios 如何避免在未结束块上两次添加UIView?
我在uiimageview中添加了一个“加载”视图,以指示正在加载映像,然后在异步调度中,我对映像充电,并在完成后删除“加载”视图,问题是,如果我调用两次此方法,“加载”视图会添加两次,而第二个视图永远不会删除 编辑: 在视图上Ios 如何避免在未结束块上两次添加UIView?,ios,objective-c,uiview,block,dispatch-async,Ios,Objective C,Uiview,Block,Dispatch Async,我在uiimageview中添加了一个“加载”视图,以指示正在加载映像,然后在异步调度中,我对映像充电,并在完成后删除“加载”视图,问题是,如果我调用两次此方法,“加载”视图会添加两次,而第二个视图永远不会删除 编辑: 在视图上 UIView *loading; on view.m loading = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)]; loading.backgroundColor = [UIColor blac
UIView *loading;
on view.m
loading = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];
loading.backgroundColor = [UIColor blackColor];
loading.alpha = 0.8;
loading.layer.cornerRadius = 10;
loading.center = CGPointMake(imageView.frame.size.width/2, imageView.frame.size.height/2);
if (![imageView.subviews containsObject:loading]) {
[imageView addSubview:loading];
}
dispatch_queue_t downloadFoto = dispatch_queue_create("Get Photo", NULL);
dispatch_async(downloadFoto, ^{
UIImage *image = [[UIImage alloc]initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[selectedImage objectForKey:@"url"]]]];
dispatch_sync(dispatch_get_main_queue(), ^{
if (image) {
[imageView setImage:image];
[imageView setNeedsLayout];
if ([imageView.subviews containsObject:loading]) {
[loading removeFromSuperview];
}
}
});
});
如果只调用一次,或者在加载已经移除之后调用,那么一切都正常,问题是如果我在块完成之前调用它
谢谢大家,这是我最后的解决方案。
if (!blackView) {
UIActivityIndicatorView *load = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
blackView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];
blackView.backgroundColor = [UIColor blackColor];
blackView.alpha = 0.8;
blackView.layer.cornerRadius = 10;
blackView.center = CGPointMake(fotoVisual.frame.size.width/2, fotoVisual.frame.size.height/2);
load.center = CGPointMake(blackView.frame.size.width/2, blackView.frame.size.height/2);
[load startAnimating];
[blackView addSubview:load];
[fotoVisual setImage:[UIImage imageNamed:@"previewImagen.png"]];
descripcionFotoView.text = [selectedImage objectForKey:@"titulo"];
}
if (![fotoVisual.subviews containsObject:blackView]) {
[fotoVisual addSubview:blackView];
}
dispatch_queue_t downloadFoto = dispatch_queue_create("Get Photo", NULL);
dispatch_async(downloadFoto, ^{
[fotoVisual setImageWithURL:[NSURL URLWithString:[selectedImage objectForKey:@"url"]]
placeholderImage:[UIImage imageNamed:@"previewImagen.png"]];
dispatch_async(dispatch_get_main_queue(), ^{
[blackView removeFromSuperview];
blackView = nil;
});
});
dispatch_release(downloadFoto);
在
dispatch\u async
块中添加加载
子视图
dispatch_queue_t downloadFoto = dispatch_queue_create("Get Photo", NULL);
dispatch_async(downloadFoto, ^{
if (!loading.superview) {
// we assume your loading view doesn't have a superview so we can add it to imageView
dispatch_sync(dispatch_get_main_queue(), ^{
[imageView addSubview:loading];
};
}
UIImage *image = [[UIImage alloc]initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[selectedImage objectForKey:@"url"]]]];
if (image) {
dispatch_sync(dispatch_get_main_queue(), ^{
[imageView setImage:image];
[imageView setNeedsLayout];
if ([imageView.subviews containsObject:loading]) {
[loading removeFromSuperview];
}
});
}
});
对于异步映像下载,您还可以使用
只需下载项目并将SDWebimage文件夹添加到您的项目中并用作文件夹
#import "UIImageView+WebCache.h"
[self.imageView setImageWithURL:[NSURL URLWithString:[selectedImage objectForKey:@"url"]]
placeholderImage:[UIImage imageNamed:@"placeholder.png"]];
这也将缓存映像。将您添加到
dispatch\u async
块中的加载
子视图
dispatch_queue_t downloadFoto = dispatch_queue_create("Get Photo", NULL);
dispatch_async(downloadFoto, ^{
if (!loading.superview) {
// we assume your loading view doesn't have a superview so we can add it to imageView
dispatch_sync(dispatch_get_main_queue(), ^{
[imageView addSubview:loading];
};
}
UIImage *image = [[UIImage alloc]initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[selectedImage objectForKey:@"url"]]]];
if (image) {
dispatch_sync(dispatch_get_main_queue(), ^{
[imageView setImage:image];
[imageView setNeedsLayout];
if ([imageView.subviews containsObject:loading]) {
[loading removeFromSuperview];
}
});
}
});
对于异步映像下载,您还可以使用
只需下载项目并将SDWebimage文件夹添加到您的项目中并用作文件夹
#import "UIImageView+WebCache.h"
[self.imageView setImageWithURL:[NSURL URLWithString:[selectedImage objectForKey:@"url"]]
placeholderImage:[UIImage imageNamed:@"placeholder.png"]];
这也将缓存映像。将您添加到
dispatch\u async
块中的加载
子视图
dispatch_queue_t downloadFoto = dispatch_queue_create("Get Photo", NULL);
dispatch_async(downloadFoto, ^{
if (!loading.superview) {
// we assume your loading view doesn't have a superview so we can add it to imageView
dispatch_sync(dispatch_get_main_queue(), ^{
[imageView addSubview:loading];
};
}
UIImage *image = [[UIImage alloc]initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[selectedImage objectForKey:@"url"]]]];
if (image) {
dispatch_sync(dispatch_get_main_queue(), ^{
[imageView setImage:image];
[imageView setNeedsLayout];
if ([imageView.subviews containsObject:loading]) {
[loading removeFromSuperview];
}
});
}
});
对于异步映像下载,您还可以使用
只需下载项目并将SDWebimage文件夹添加到您的项目中并用作文件夹
#import "UIImageView+WebCache.h"
[self.imageView setImageWithURL:[NSURL URLWithString:[selectedImage objectForKey:@"url"]]
placeholderImage:[UIImage imageNamed:@"placeholder.png"]];
这也将缓存映像。将您添加到
dispatch\u async
块中的加载
子视图
dispatch_queue_t downloadFoto = dispatch_queue_create("Get Photo", NULL);
dispatch_async(downloadFoto, ^{
if (!loading.superview) {
// we assume your loading view doesn't have a superview so we can add it to imageView
dispatch_sync(dispatch_get_main_queue(), ^{
[imageView addSubview:loading];
};
}
UIImage *image = [[UIImage alloc]initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[selectedImage objectForKey:@"url"]]]];
if (image) {
dispatch_sync(dispatch_get_main_queue(), ^{
[imageView setImage:image];
[imageView setNeedsLayout];
if ([imageView.subviews containsObject:loading]) {
[loading removeFromSuperview];
}
});
}
});
对于异步映像下载,您还可以使用
只需下载项目并将SDWebimage文件夹添加到您的项目中并用作文件夹
#import "UIImageView+WebCache.h"
[self.imageView setImageWithURL:[NSURL URLWithString:[selectedImage objectForKey:@"url"]]
placeholderImage:[UIImage imageNamed:@"placeholder.png"]];
这也会缓存图像。看起来您遇到的问题是每次都在创建一个新的
加载
视图,这不是您想要的。每次创建新的加载视图时,您的[imageView.subview containsObject:loading]
将永远不会为真
您可以更改创建逻辑来执行如下检查
if (!loading) {
// configure loading
[imageView addSubview:loading];
}
然后将您的回拨修改为
dispatch_sync(dispatch_get_main_queue(), ^{
if (image) {
[imageView setImage:image];
[imageView setNeedsLayout];
[loading removeFromSuperview];
loading = nil;
}
});
您使用dispatch\u sync
而不是dispatch\u async
有什么具体原因吗?您遇到的问题似乎是每次都要创建一个新的加载
视图,这不是您想要的。每次创建新的加载视图时,您的[imageView.subview containsObject:loading]
将永远不会为真
您可以更改创建逻辑来执行如下检查
if (!loading) {
// configure loading
[imageView addSubview:loading];
}
然后将您的回拨修改为
dispatch_sync(dispatch_get_main_queue(), ^{
if (image) {
[imageView setImage:image];
[imageView setNeedsLayout];
[loading removeFromSuperview];
loading = nil;
}
});
您使用dispatch\u sync
而不是dispatch\u async
有什么具体原因吗?您遇到的问题似乎是每次都要创建一个新的加载
视图,这不是您想要的。每次创建新的加载视图时,您的[imageView.subview containsObject:loading]
将永远不会为真
您可以更改创建逻辑来执行如下检查
if (!loading) {
// configure loading
[imageView addSubview:loading];
}
然后将您的回拨修改为
dispatch_sync(dispatch_get_main_queue(), ^{
if (image) {
[imageView setImage:image];
[imageView setNeedsLayout];
[loading removeFromSuperview];
loading = nil;
}
});
您使用dispatch\u sync
而不是dispatch\u async
有什么具体原因吗?您遇到的问题似乎是每次都要创建一个新的加载
视图,这不是您想要的。每次创建新的加载视图时,您的[imageView.subview containsObject:loading]
将永远不会为真
您可以更改创建逻辑来执行如下检查
if (!loading) {
// configure loading
[imageView addSubview:loading];
}
然后将您的回拨修改为
dispatch_sync(dispatch_get_main_queue(), ^{
if (image) {
[imageView setImage:image];
[imageView setNeedsLayout];
[loading removeFromSuperview];
loading = nil;
}
});
您使用dispatch\u sync
而不是dispatch\u async
有什么具体原因吗?这会有什么不同?我的答案中添加了一个编辑。请看一看,我试过那个sdk,效果很好,但仍然需要加载视图。您是否尝试过检查您的加载是否有类似于if(loading.superview)
的超级视图?请参阅上面我编辑的代码是的,尝试了相同的结果,再加上paul的答案,我得到了完整的答案,+1对于sdk来说太棒了;)这会有什么不同?我的答案中添加了一个编辑。请看一看,我试过那个sdk,效果很好,但仍然需要加载视图。您是否尝试过检查您的加载是否有类似于if(loading.superview)
的超级视图?请参阅上面我编辑的代码是的,尝试了相同的结果,再加上paul的答案,我得到了完整的答案,+1对于sdk来说太棒了;)这会有什么不同?我的答案中添加了一个编辑。请看一看,我试过那个sdk,效果很好,但仍然需要加载视图。您是否尝试过检查您的加载是否有类似于if(loading.superview)
的超级视图?请参阅上面我编辑的代码是的,尝试了相同的结果,再加上paul的答案,我得到了完整的答案,+1对于sdk来说太棒了;)这会有什么不同?我的答案中添加了一个编辑。请看一看,我试过那个sdk,效果很好,但仍然需要加载视图。您是否尝试过检查您的加载是否有类似于if(loading.superview)
的超级视图?请参阅上面我编辑的代码是的,尝试了相同的结果,再加上paul的答案,我得到了完整的答案,+1对于sdk来说太棒了;)加载
是ivar还是局部变量?你能展示它的创建吗…是一个ivar…我将编辑我的问题你可以尝试从imageview中删除每个视图,[imageview.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];containsObject将始终为false,因为每次创建新的加载视图时。尝试将标记添加到加载视图,并检查图像视图是否有带标记的视图。如果有,您可以确保已经添加了itIs加载