cph2117
cph2117

Reputation: 2681

Overriding UIImageView's image getter/setter methods

I'm subclassing a UIImageView, so that each time the image property is set an animation occurs. The following was successful:

import UIKit

class AnimatedImageView: UIImageView {

var img: UIImage! {
    get {
        return self.image
    }
    set {
        self.image = newValue

        UIView.animateWithDuration(0.5, delay: 0.4, usingSpringWithDamping: 0.2, initialSpringVelocity: 5.0, options: .CurveEaseIn, animations: {_ in

            self.transform = CGAffineTransformMakeScale(1.1, 1.1);

            }, completion: {_ in
                self.transform = CGAffineTransformIdentity;
        })
    }
}

This is no surprise. I subclassed UIImageView and added an entirely new variable called 'img', which in turn modifies UIImageView's 'image' property.

The issue is that the end-user could conceivably still alter AnimatedImageView's 'image' property.

import UIKit

class AnimatedImageView: UIImageView {

override var image: UIImage! {
 get {
     return self.image
 }
 set {
    self.image = newValue

    UIView.animateWithDuration(0.5, delay: 0.4, usingSpringWithDamping: 0.2, initialSpringVelocity: 5.0, options: .CurveEaseIn, animations: {_ in

        self.transform = CGAffineTransformMakeScale(1.1, 1.1);

        }, completion: {_ in
            self.transform = CGAffineTransformIdentity;
    })
 }
}

Sure enough this causes a stackoverflow because when I call self.image = newValue it repeatedly calls the setter method that I've overridden in my subclass. So, what's the right way to override the getter/setter methods of the 'image' property on UIImageView

Upvotes: 7

Views: 3318

Answers (2)

Alexander Gingell
Alexander Gingell

Reputation: 372

An alternative to using super.image would be to reference the image via the ivar _image. This references it directly, without calling the getter, and avoids the loop.

import UIKit

class AnimatedImageView: UIImageView {

override var image: UIImage! {
 get {
     return _image
 }
 set {
    _image = newValue

    UIView.animateWithDuration(0.5, delay: 0.4, usingSpringWithDamping: 0.2, initialSpringVelocity: 5.0, options: .CurveEaseIn, animations: {_ in

        self.transform = CGAffineTransformMakeScale(1.1, 1.1);

        }, completion: {_ in
            self.transform = CGAffineTransformIdentity;
    })
 }

Upvotes: 0

TheEye
TheEye

Reputation: 9346

Just use super.image instead, that will prevent a loop.

Upvotes: 12

Related Questions