Beginning iOS Animations - Part 3: Intermediate | Ray Wenderlich

Build upon basic constraint animations and learn more ways to create Auto Layout animations.


This is a companion discussion topic for the original entry at https://www.raywenderlich.com/3882-beginning-ios-animations/lessons/3

Problem with Challenge for lesson 3.

As I add

let conX = imageView,

I get an error Use of unresolved identifier ‘imageView’

This occurs for ConBottom, width, height.

I add the line NSlayoutConstraint.
I still have 4 error messages.

At this point you suggest running the app.
Which obviously wont.

I noticed some differences in the showItem method lines 94-95

line 94
Challenge Start : makreImageView(index:index)
Challenge Finish: let imageView = makreImageView(index:index)

line 95
Challenge Start: blank
Challenge Finish: view.addSubview(imageView)

we are not asked to amend these lines in the challenge.

I added them in and still get the same error

Any thoughts as to what else may be the cause.

Thanks

I’ve the same problem, but I resolve this like this:

  1. make property "var imageView: UIImageView! " in class ViewController
  2. remove “let” before imageView
  3. follow the steps as written in challenge documentation.

Hi there!

So sorry for the long delay on getting back to you, and thanks for letting me know about this problem. I had actually made a change to the makeImageView method in the Challenge End project, so that it would return a UIImageView, that I completely missed adding back into the Challenge Start project. The difference in showItem you noticed should also have made it into the starter project. I’ve updated the downloadable materials and everything should work as expected now!

Thanks also to @ilmaros for sorting out another solution :smile_cat:

In Demo Start (video), have one more code, i don’t understand. This is code:
titleLabel.superview?.constraints.forEach({ (constraint) in
print(" -> (constraint.description)\n")
}
I think titleLabel.superview == Menu View (view contains Label), but result display in console no same.
From storyboard, i see Menu View have eight constraint but screen console is five constraint.
In screen console, i see one constraint:

UIButton:0x7fc2fe506250’+’.centerY == UILabel:0x7fc301009eb0’Select Item’.centerY (active)>

Sorry because i can put only one image

But i not see in constraint of Menu View in Storyboard.
I don’t understand activity of titleLabel.superview ?

Hi @thangtruong!

You’re understanding the superview part correctly. The confusion is around what the constraints property is doing, and we didn’t explain it well in the video. The documentation for the constraints property isn’t very helpful either, simply stating it is “The constraints held by the view.” This can be confusing because constraints that affect a view (the constraints listed in the Size Inspector) are not always the same as the constraints held by that view (the constraints listed in the document outline).
In Apple’s own words, from their Auto Layout Guide:

“Constraints are held by the closest view that contains both items in the constraint. For this calculation, each view contains itself and all its subviews, and the top and bottom layout guides are contained by the scene’s root view.”

If you take a look in the document outline, you can see this visualized. The constraints are arranged beneath the views they are held by. In your screenshot, you can see five constraints beneath the Menu View, and these will be the same five constraints you can see printed in the console below in Visual Format Language. The number of constraints may not always match up, as the constraints property will also hold any constraints which have been created for you. You could see this in action if you printed out the constraints on titleLabel itself.

The specific constraint you asked about is the constraint between the centerY properties of the Button Menu button and the Title Label. Both are subviews of the Menu View, so Menu View holds that constraint. If you give this constraint an identifier in the storyboard, like we do with TitleCenterY in the video, you can see that identifier printed out in the description in the console.

I hope this answers your question. Thanks for asking about this, and I’ll make sure it’s explained correctly in the next update!

Hi there,
I am really confused of how the constraints draw the UI. In the Challenge part of showItem function, followed by the tutorial, we add new constraints, I use view.layoutIfNeeded() to update the UI and i have not add the animation yet.
I use two print to confirm the result , the code as follows

func showItem(_ index: Int) {
    print("tapped item \(index)")
    let imageView = makeImageView(index: index)
    view.addSubview(imageView)

let conX = imageView.centerXAnchor.constraint(equalTo: view.centerXAnchor)
let conBottom = imageView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: imageView.frame.height)

let conWidth = imageView.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.33, constant: -50)

let conHeight = imageView.heightAnchor.constraint(equalTo: imageView.widthAnchor)

NSLayoutConstraint.activate([conX, conBottom, conWidth, conHeight])

print("imageView.frame.size.height  is \(imageView.frame.height)")
//TODO: Create and animate some constraints!

view.layoutIfNeeded()

 print("imageView.frame.size.height  is \(imageView.frame.size.height)")

The console shows :
tapped item 6
imageView.frame.size.height is 50.0
imageView.frame.size.height is 73.5

I am confused how does the constraints draw the UI. The bottom constraint is depending on the frame’s height , and the height also changed depending of its height constraint.
But according to the position of the image view,

it seems that the bottom constraint’s constant is NOT ITS OWN HEIGHT VALUE!! Because I think if it is its own height value, it should exactly locate under the screen and we should never seen it rather than we can see a part of it, right ??

I am really confused and because of that, I can not understand how does the animation run. Thank you for explaining.