2014-09-01 8 views
0

У меня есть IBOutlet до UIImageView под названием 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, изображение не будет заменено.

Почему это происходит? ПОМОГИТЕ!

EDIT Теперь изображение меняется, но возвращается через секунду или два. Это изменение, внесенное мной в функцию 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]; 
       }); 
      } 

     }); 

So close.

+0

Не могли бы вы лучше объяснить, что хотите, и что у вас на самом деле? И можете ли вы также опубликовать скриншот? – Serluca

+0

Вы получаете изображение с сервера? –

+0

Я думаю, что, возможно, ваш viewDidload был вызван после того, как вы установили новое изображение. Отделите код, который установил образ по умолчанию (в вашем представленииDidload), затем добавьте NSLog(), чтобы знать, когда он вызван. –

ответ

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 ссылке. Таким образом, вы можете попытаться получить знать, когда вызывается этот метод или на некоторое время вы можете вызвать метод делегата явно нравится:

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 в большинстве случаев

Если это не работает, кажется, что первая часть вашего кода запускается по какой-либо причине перед второй частью. я бы поставил несколько вызовов регистрации, чтобы проверить, каков реальный порядок выполнения.

, если все остальное терпит неудачу, вы можете реализовать действительно Hacky решение, задерживая вызов ..

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

также, если это решает, он может дать вам подсказку о неожиданной коде работает в этих 2-х секунд ..

+0

Пробовал без setNeedsDisplay. Проблема осталась. –

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 позволяет также кэшировать изображения.

Смежные вопросы