如何检测UIImageView的图片是否发生变化

How to detect if the image of UIImageView has changed

我有一个应用程序,用户可以在其中选择相机胶卷中的图像,然后将该图像加载到 UIImageView。但是,如果图像很大,则在所选图像实际出现在 UIImageView 之前会有延迟(设置图像不会在 main thread 上执行,因此 UI 不会被冻结) .在设置图像之前,我想显示一个 activity 指示器,通知用户应用程序没有冻结,它只是在加载图像。但是我不知道如何检测图像何时设置在 UIImageView 中以隐藏 activity 指示器。我猜也许 KVO 可以在这里提供帮助,但我不确定如何正确实施它。

抱歉这个菜鸟问题! :)

使用 KVO 观察 UIImageView 图像 属性。添加代码以停止微调器代替 NSLog(@"imageReady");。

@implementation ViewController {
   __weak IBOutlet UIImageView *_imageView;
}

- (void)viewDidLoad {
   [super viewDidLoad];
   // Do any additional setup after loading the view, typically from a nib.
   [_imageView addObserver:self forKeyPath:@"image" options:NSKeyValueObservingOptionNew context:NULL];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
  if ([keyPath isEqualToString:@"image"]) {
     //Image ready
     //Stop loading spinner.
     NSLog(@"imageReady");
  }
}

如果您使用 swift,您还可以创建 UIImageView 子类并覆盖 image 属性 以观察 didSet 的值。只记得设置超类的图像。

class ImageView: UIImageView {
    override var image: UIImage? {
        didSet {
            super.image = image
            println("Image Set")
        }
    }
}

1- 创建一个 NSKeyValueObservation 属性

2-用yourImageView.observe...

初始化viewDidLoad中的属性

3- 将其设置为监听 \.image 并将选项设置为 [.old, .new]

4-删除deinit中的观察者

@IBOutlet var yourImageView: UIImageView!

var observer: NSKeyValueObservation? // 1.

override func viewDidLoad() {
    super.viewDidLoad()

    observer = nil // not necessary but still

    // 2.                            // 3.
    observer = yourImageView.observe(\.image, options: [.old, .new], changeHandler: { [weak self](imageView,_) in
            
        guard let img = imageView.image else { return }

        print("an image was set on your imageView, do something with the image", img)
    })
}

deinit {

    observer = nil // 4.
}