1

I'm creating a custom view with 2 image views, and I want to be able to animate from one to another, here's my code:

class FlashCard: UIView {

required init?(coder: NSCoder) {
    super.init(coder: coder)

    let firstImageView = UIImageView(frame: self.frame)
    firstImageView.image = UIImage(named: "Lightning")
    addSubview(firstImageView)

    let secondImageView = UIImageView(frame: frame)
    secondImageView.image = UIImage(named: "Tifa")
    addSubview(secondImageView)
    secondImageView.isHidden = true

}

func showBack() {
    UIView.transition(from: firstImageView, to: secondImageView, duration: 1.0, options: UIViewAnimationOptions.transitionCrossDissolve, completion: nil)
}
}

But in my showBack function, I got the error: use of unresolved identifier.

How do I properly access firstImageView and secondImageView?

Bright
  • 5,699
  • 2
  • 50
  • 72

2 Answers2

2

You must use two properties:

var firstImageView: UIImageView!
var secondImageView: UIImageView!

at the moment you have the two UIImageViewin the local scope of init so you cannot use it in another class method but just in the init scope.

So:

class FlashCard: UIView {

    var firstImageView: UIImageView!
    var secondImageView: UIImageView!

    required init?(coder: NSCoder) {
        super.init(coder: coder)

        firstImageView = UIImageView(frame: self.frame)
        firstImageView.image = UIImage(named: "Lightning")
        addSubview(firstImageView)

        secondImageView = UIImageView(frame: frame)
        secondImageView.image = UIImage(named: "Tifa")
        addSubview(secondImageView)
        secondImageView.isHidden = true
    }

    func showBack() {
        UIView.transition(from: firstImageView, to: secondImageView, duration: 1.0, options: UIViewAnimationOptions.transitionCrossDissolve, completion: nil)
    }
}
Yury
  • 6,044
  • 3
  • 19
  • 41
Marco Santarossa
  • 4,058
  • 1
  • 29
  • 49
  • Better to declare this properties as implicitly unwrapped, since looks like object of this type always should have two image views – Yury Sep 02 '16 at 07:48
  • Sure! Just waiting for the timer to go off – Bright Sep 02 '16 at 07:52
  • 1
    @ShadowOf you don't need implicitly unwrapped since you assign the value in the init, am I missing something? – Marco Santarossa Sep 02 '16 at 07:54
  • 1
    This answer would be better if both properties were `let firstImageView = UIImageView()`, and then frames were assigned in the init. There's no need for them to be variables, but they must have values before super init can be called. – jrturton Sep 02 '16 at 07:58
  • Yes, you miss that properties should be initialized before super init called – Yury Sep 02 '16 at 08:02
  • 1
    @ShadowOf So why they are not initialized before `super.init`? – Sulthan Sep 02 '16 at 08:05
  • @Sulthan [this](http://stackoverflow.com/revisions/39286938/2) revision will not compile due to pointed problem, don't you agree? – Yury Sep 02 '16 at 08:08
  • 1
    @ShadowOf I do agree but I wonder why not put the initialization before `super.init`. – Sulthan Sep 02 '16 at 08:11
  • @Sulthan sure we can do that. jrturton's offer is best here. I offered implicitly unwrapped because it was minimal changes from original answer. – Yury Sep 02 '16 at 08:14
  • @ShadowOf the original version was right, I got an error due to the initialization problem, see this post for more: http://stackoverflow.com/questions/24021093/error-in-swift-class-property-not-initialized-at-super-init-call – Bright Sep 02 '16 at 08:23
  • @jrturton can you elaborate more with an answer? – Bright Sep 02 '16 at 08:24
  • @BrightFuture please be accurate. First and third (current) revisions of this answer are correct. Probably you mixed them? – Yury Sep 02 '16 at 08:28
  • @BrightFuture your edit will be rejected, current one still [third](http://stackoverflow.com/revisions/39286938/3) version. Please, note that it's just the *same* as first, properties still `Optional`, you just don't need to unwrap them – Yury Sep 02 '16 at 08:33
2

There is no need for the image views to be variables, of whatever flavour of optional.

class FlashCard: UIView {

    let firstImageView = UIImageView()
    let secondImageView: UIImageView()

    required init?(coder: NSCoder) {
        super.init(coder: coder)

        firstImageView.frame = frame
        firstImageView.image = UIImage(named: "Lightning")
        addSubview(firstImageView)

        secondImageView.frame = frame
        secondImageView.image = UIImage(named: "Tifa")
        addSubview(secondImageView)
        secondImageView.isHidden = true
    }

    func showBack() {
        UIView.transition(from: firstImageView, to: secondImageView, duration: 1.0, options: UIViewAnimationOptions.transitionCrossDissolve, completion: nil)
    }
}

Properties of a class must be initialised before the super initialiser is called, which is why the other answer used implicitly unwrapped optional variables.

jrturton
  • 118,105
  • 32
  • 252
  • 268