2014-09-01 63 views
0

我有一個IBOutletUIImageView調用attachmentImage。默認情況下,它具有通過故事板添加的佔位符圖像。不能更改UIImageView圖像

如果圖像已經存在,則使用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]; 
       }); 
      } 

     }); 

太近了。

+0

你能更好地解釋你想要擁有什麼,以及你有什麼實際?你也可以張貼一些截圖嗎? – Serluca 2014-09-03 23:10:59

+0

你正在從服務器獲取圖像? – 2014-09-08 07:37:35

+0

我想你可能在設置新圖片後調用了viewDidload。分開設置默認圖像的代碼(在viewDidload中),然後添加一個NSLog()以知道它何時被調用。 – 2014-09-09 14:46:03

回答

0

這工作,但無法弄清楚什麼是錯誤的。事做隊列:/

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]; 
} 
0

我認爲你可以清理很多你的代碼。

我不知道,如果我知道你想什麼做的,但試圖實現這種代碼:

-(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;爲時尚早。

0

我想委託方法

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

     } 

    }); 
1

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

如果這不起作用,看起來代碼的第一部分由於某種原因在第二部分之前運行。我會把一些日誌記錄調用來檢查什麼是執行的真正的順序。

如果一切都失敗了,你可以通過延遲調用實現一個真正哈克的解決方案..

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

還是否能解決它,它可以給你那些2秒內部運行的一些意想不到的代碼線索..

+0

嘗試沒有setNeedsDisplay。問題仍在。 – 2014-09-10 19:47:14

0

似乎是一個怪異的行爲,也許調用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... 
} 
0

在我看來,問題是,它需要時間從URL下載圖像。 在這種情況下,我會使用SDWebImage或已經提到PromiseKit

SDWebImage也允許緩存圖像。