Ios 无法更改UIImageView图像

Ios 无法更改UIImageView图像,ios,uiimageview,uiimage,Ios,Uiimageview,Uiimage,我有一个IBOutlet到UIImageView的名为attachmentImage。默认情况下,它有一个通过故事板添加的占位符图像 如果图像已经存在,则使用setImageWithURL显示图像。这可以工作并显示图像。从viewDidLoad调用 [self.attachmentImage setImageWithURL:[NSURL URLWithString:attachmentImageURL]]; self.attachmentImage.contentMode = UIViewCon

我有一个
IBOutlet
UIImageView
的名为
attachmentImage
。默认情况下,它有一个通过故事板添加的占位符图像

如果图像已经存在,则使用
setImageWithURL
显示图像。这可以工作并显示图像。从
viewDidLoad调用

[self.attachmentImage setImageWithURL:[NSURL URLWithString:attachmentImageURL]];
self.attachmentImage.contentMode = UIViewContentModeScaleAspectFill;
self.attachmentImage.clipsToBounds = YES;
[attachmentImage setNeedsDisplay];
如果图像不存在,则从库中选择图像并按此方式添加

- (void)takeController:(FDTakeController *)controller gotPhoto:(UIImage *)photo withInfo:(NSDictionary *)info {
    [attachmentImage setImage:nil];
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
    self.attachmentImage.contentMode = UIViewContentModeScaleAspectFill;
    [self.attachmentImage setImage:photo];
    self.attachmentImage.clipsToBounds = YES;
    [attachmentImage setNeedsDisplay];
}
如果没有添加图像(除占位符外),则上传有效。但如果图像视图将图像设置为
setImageWithURL
,则不会替换该图像

为什么会这样?救命啊

编辑现在图像确实会更改,但一两秒钟后会恢复。这是我对
setImageWithURL
函数所做的更改

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        dispatch_async(queue, ^{
            attachmentImageURL = [NSString stringWithFormat:@"%@%@", BaseURL, imgpath];
            NSURL *url = [NSURL URLWithString:attachmentImageURL];
            NSData *data = [NSData dataWithContentsOfURL:url];

            if (![data isEqualToData:nil]) {
                UIImage *image = [UIImage imageWithData:data];
                dispatch_async(dispatch_get_main_queue(), ^{
                    attachmentImage.image = image;
                    self.attachmentImage.contentMode = UIViewContentModeScaleAspectFill;
                    self.attachmentImage.clipsToBounds = YES;
                    [attachmentImage setNeedsDisplay];

                    [self applyImageViewConstraints];
                });
            }

        });

非常接近。

我认为您可以清理大量代码

我不知道我是否理解您想要什么,但请尝试实现以下代码:

-(void)viewDidLoad{
    [super viewDidLoad];
    self.attachmentImage.contentMode = UIViewContentModeScaleAspectFill; // You can also select the content mode in the storyboard
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(queue, ^{
        attachmentImageURL = [NSString stringWithFormat:@"%@%@", BaseURL, imgpath];
        NSURL *url = [NSURL URLWithString:attachmentImageURL];
        NSData *data = [NSData dataWithContentsOfURL:url];

        if (data) {
            UIImage *image = [UIImage imageWithData:data];
            dispatch_async(dispatch_get_main_queue(), ^{
                self.attachmentImage.image = image;
            });
        }else{
            // Do something
        }

    });
}

可能是因为调用方法
-(void)takeController:(FDTakeController*)controller gotPhoto:(UIImage*)photo with info:(NSDictionary*)info太早了。

我认为委托方法

- (void)takeController:(FDTakeController *)controller gotPhoto:(UIImage *)photo withInfo:(NSDictionary *)info 
您所说的是在imageview url中设置图像之前调用。 因此,您可以尝试了解何时调用此方法,或者暂时可以显式调用委托方法,如下所示:

dispatch_async(queue, ^{
        attachmentImageURL = [NSString stringWithFormat:@"%@%@", BaseURL, imgpath];
        NSURL *url = [NSURL URLWithString:attachmentImageURL];
        NSData *data = [NSData dataWithContentsOfURL:url];

        if (data) {
            UIImage *image = [UIImage imageWithData:data];
            dispatch_async(dispatch_get_main_queue(), ^{
                self.attachmentImage.image = image;
            });
        }else{
            // Do call delegate method with needed arguments supplied

[fdTakeController.delegate takeController:controller gotPhoto:photo withInfo:info ];

        }

    });

我会先尝试删除setNeedsDisplay,在大多数情况下UIImageView不需要它

如果这不起作用,那么代码的第一部分似乎是在第二部分之前出于某种原因运行的。我会进行一些日志调用来检查真正的执行顺序

如果所有其他方法都失败了,您可以通过延迟呼叫来实现一个真正的黑客解决方案

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC),    
dispatch_get_main_queue(), ^{ .... }

此外,如果这解决了它,它可以给你一个线索,一些意想不到的代码在这2秒钟内运行

似乎是一种奇怪的行为,可能对setImageWithURL的调用延迟了设置图像的代码的执行(如果确实存在),也许您可以尝试将setImageWithURL更改为以下内容:

// In your class definition
PMKPromise* setImageFromURLPromise;

// In your implementation
-(void) setImageWithURL {
     _setImageFromURLPromise = [NSURLConnection GET:@[NSString stringWithFormat:@"%@%@", BaseURL, imgpath]].then(^(UIImage *image) {
        self.attachmentImage.image = image;
    }).catch(^(NSError *error){
        // error handling if needed?
    });
}
在实际尝试从相机/照片库加载照片之前,您可以检查:

if (setImageFromURLPromise == nil || [setImageFromURLPromise resolved]) {
   // The promise is resolved, no more race conditions or rare behavior, take the photo or load from the library.
} else {
   // Display a message that the image from URL is still loading...
}

这起作用了,但无法找出问题所在。与队列有关的内容:/

viewDidLoad

attachmentImageURL = [NSString stringWithFormat:@"%@%@", BaseURL, imgpath];
        NSLog(@"the image url is %@", attachmentImageURL);
        [self.attachmentImage setImageWithURL:[NSURL URLWithString:attachmentImageURL]];
        self.attachmentImage.contentMode = UIViewContentModeScaleAspectFill;
        self.attachmentImage.clipsToBounds = YES;
        [attachmentImage setNeedsDisplay];
        [self applyImageViewConstraints];
以及上传方法

- (void)takeController:(FDTakeController *)controller gotPhoto:(UIImage *)photo withInfo:(NSDictionary *)info {

    NSLog(@"In takeController");

    dispatch_async(dispatch_get_main_queue(), ^{attachmentImage.image = nil;});

    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
    self.attachmentImage.contentMode = UIViewContentModeScaleAspectFill;
    dispatch_async(dispatch_get_main_queue(), ^{attachmentImage.image = photo;});
    self.attachmentImage.clipsToBounds = YES;
    selectedImage = photo;

    [self applyImageViewConstraints];
}

在我看来,问题在于从URL下载图像需要时间。 在这种情况下,我会使用或已经提到


还允许缓存图像。

您能更好地解释一下您想要什么,以及您实际拥有什么吗?你们也可以发布一些屏幕截图吗?你们正在从服务器上获取图像??我想也许你们的viewDidload在你们设置了新图像后被调用了。分离设置默认图像的代码(在viewDidload中),然后添加一个NSLog(),以了解它何时被调用。您说它在2秒钟后恢复,您是否检查过setImageWithURL没有被多次调用?特别是attachmentImage.image=image;事实并非如此。解决了。添加答案。但我不知道是什么导致了这个问题/