簡體   English   中英

無法更改UIImageView圖像

[英]Cannot change UIImageView image

我有一個到UIImageViewIBOutlet ,名為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];
                });
            }

        });

很近。

我會先嘗試刪除setNeedsDisplay-在大多數情況下,不需要UIImageView

如果這不起作用,則似乎代碼的第一部分由於某種原因在第二部分之前運行。 我會進行一些日志記錄調用,以檢查真正的執行順序。

如果其他所有方法均失敗,則可以通過延遲呼叫來實施真正的解決方案。

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

如果解決了這個問題,也可以為您提供這2秒內運行的一些意外代碼的線索。

我認為您可以清理很多代碼。

我不知道我是否了解您想要什么,但是嘗試實現以下代碼:

-(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 withInfo:(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 ];

        }

    });

似乎是一種奇怪的行為,也許對setImageWithURL的調用會延遲設置圖像的代碼的執行(如果確實存在),也許您可​​以嘗試PromiseKit並將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下載圖像需要花費時間。 在這種情況下,我將使用SDWebImage或已經提到的PromiseKit

SDWebImage也允許緩存圖像。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM