Tkas
Tkas

Reputation: 347

How to bind image to UIImageView with rxswift?

I have viewModel:

class EditFoodViewViewModel {
    private var food: Food

    var foodImage = Variable<NSData>(NSData())

    init(food: Food) {
        self.food = food
        self.foodImage.value = food.image!
    }
}

And ViewController:

class EditFoodViewController: UIViewController {
    public var food: EditFoodViewViewModelType?
    @IBOutlet weak var foodThumbnailImageView: UIImageView!

    override func viewDidLoad() {
        super.viewDidLoad()

        guard let foodViewModel = food else { return }
        foodViewModel.foodImage.asObservable().bind(to: foodThumbnailImageView.rx.image).disposed(by: disposeBag)
  }
}

In the last line of viewController (where my UIImageView) a get error:

Generic parameter 'Self' could not be inferred

How to solve my problem? How to set image to imageView with rxSwift?

Upvotes: 1

Views: 5590

Answers (1)

Daniel T.
Daniel T.

Reputation: 33967

Almost invariably, when you see the error: "Generic parameter 'Self' could not be inferred", it means that the types are wrong. In this case you are trying to bind an Observable<NSData> to an Observable<Image?>.

There's a few other issues with your code as well.

  • it is very rare that a Subject type should be defined with the var keyword and this is not one of those rare times. Your foodImage should be a let not a var.

  • Variable has been deprecated; don't use it. In this case, you don't even need a subject at all.

  • NSData is also inappropriate in modern Swift. Use Data instead.

Based on what you have shown here, I would expect your code to look more like this:

class EditFoodViewViewModel: EditFoodViewViewModelType {
    let foodImage: Observable<UIImage?>

    init(food: Food) {
        self.foodImage = Observable.just(UIImage(data: food.image))
    }
}

class EditFoodViewController: UIViewController {

    @IBOutlet weak var foodThumbnailImageView: UIImageView!
    public var food: EditFoodViewViewModelType?
    private let disposeBag = DisposeBag()

    override func viewDidLoad() {
        super.viewDidLoad()

        guard let foodViewModel = food else { return }
        foodViewModel.foodImage
            .bind(to: foodThumbnailImageView.rx.image)
            .disposed(by: disposeBag)
    }
}

Upvotes: 1

Related Questions