【问题标题】:Cannot change UIImageView image无法更改 UIImageView 图像
【发布时间】:2014-09-01 18:29:40
【问题描述】:

我有一个IBOutletUIImageView,称为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];
                });
            }

        });

如此接近。

【问题讨论】:

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

标签: ios uiimageview uiimage


【解决方案1】:

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

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

如果所有其他方法都失败了,您可以通过延迟调用来实现一个非常老套的解决方案..

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

如果这解决了它,它可以给你一些在这 2 秒内运行的意外代码的线索..

【讨论】:

    【解决方案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; 太早了。

    【讨论】:

      【解决方案3】:

      我认为是委托方法

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

      【讨论】:

        【解决方案4】:

        似乎是一个奇怪的行为,也许对 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...
        }
        

        【讨论】:

          【解决方案5】:

          这有效,但无法弄清楚出了什么问题。与队列有关:/

          来自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];
          }
          

          【讨论】:

            【解决方案6】:

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

            SDWebImage 也允许缓存图像。

            【讨论】:

              猜你喜欢
              • 2018-12-05
              • 1970-01-01
              • 2021-02-16
              • 1970-01-01
              • 1970-01-01
              • 2013-04-24
              • 1970-01-01
              • 1970-01-01
              • 2018-03-23
              相关资源
              最近更新 更多