Bummer! This is just a preview. You need to be signed in with a Basic account to view the entire video.
Start a free Basic trial
to watch this video
We managed to resize the image to fit the screen by zooming out but the image is pinned to the top. In this video, let's figure out a way to update the constraints to position the image accurately and allow for zooming.
-
0:00
In the last video, we managed to get the photo to fit on the screen.
-
0:05
Again let's take a quick second to understand what we did.
-
0:08
When we tapped on the photo zoom controller at the start of the last video,
-
0:12
it started off zoomed in and took up the entire scrollable space, this is expected.
-
0:17
iPhone cameras are pretty good and
-
0:19
what we're seeing there is the actual size of the image at 100% zoom.
-
0:24
Since we set the content size of the scrollView to the bound size of this
-
0:28
image, what we saw on the screen was a portion of the scrollable area.
-
0:32
To make this image fit,
-
0:34
we need it to scale it down from the 100% zoom to something that fit on the screen.
-
0:40
And this is where our calculation came in.
-
0:43
We determined how much larger than the screen the image was, and
-
0:47
again we did this for both height and width.
-
0:50
If the image width was three times bigger than the screen width,
-
0:53
we divided one by that amount to get a scale factor, 0.33 in this case.
-
0:59
Now not all images we take in our app are the same dimensions,
-
1:02
some are in landscape and others are in portrait.
-
1:05
And even the preloaded images in the image library of those,
-
1:08
they're different height and width.
-
1:10
So to make all these images fit on the screen, we need to figure out which
-
1:15
was the minimum ratio between the two, is the height smaller, or the width ratio?
-
1:19
Once we've determined that, we set the current zoomScale of the scrollView so
-
1:23
that the scrollView zooms out and fits the entire scrollable area onto the screen.
-
1:29
In doing so, we managed the show the entire photo, which is great.
-
1:33
We also set the minimumZoomScale of the scrollView to the same value because we're
-
1:37
trying to implement pinch to zoom in, not zoom out.
-
1:40
We don't want to make the image any smaller.
-
1:43
So after doing all that,
-
1:44
we ended up with an image that did fit, both pin to the top of the screen.
-
1:48
Now this is a constraint related issue.
-
1:52
When we set up the constraints initially,
-
1:53
we just pinned it to the edges of the scrollView.
-
1:56
The image sits inside the scrollView at the origin in the top left, and
-
2:01
when we zoom out of the image to make it fit,
-
2:03
there's all this empty scrollView space at the bottom.
-
2:06
So let's fix this by writing a new function.
-
2:09
We'll say func updateConstraintsForSize,
-
2:14
and this method will take a single argument size of type CGSize.
-
2:24
Much like we updated the minimumZoomScale, we're going to update the constraints we
-
2:28
added earlier to account for this new size.
-
2:31
To do that, we need a reference of the constraints, let's go ahead and
-
2:34
grab those.
-
2:36
So we'll go main.storyboard, to the photoZoomController,
-
2:41
we'll open up the assistant editor, and of course is in load, so
-
2:46
we'll grab the photoZoomController, and option Enter to get there, there we go.
-
2:52
Now I'm going to do this in the document outline cuz the constraints are listed
-
2:56
right here, and actually we want these ones, there we go.
-
3:03
So we'll start with the image views leading constraints,
-
3:06
that’s this one right here, we'll control drag and it'll say
-
3:12
imageViewLeadingConstraint, okay.
-
3:17
Next we'll get the image views trailing constraint,
-
3:24
imageViewTrailingConstraint.
-
3:30
And then and the next is the top and the bottom.
-
3:36
ImageViewTopConstraint, and
-
3:41
image, imageViewBottomConstraint.
-
3:47
You'll notice that the center x and center y are also there,
-
3:50
but we're gonna ignore those because remember that gets removed at build time.
-
3:56
And now we have all our constraints.
-
3:59
What we want to do now is center the image vertically and
-
4:03
horizontally, and this requires doing a bit of math.
-
4:07
Let's start with the vertical spacing at the top.
-
4:11
First, we want to find out, after the image has been resized,
-
4:14
how much empty space is there?
-
4:16
And we can do this by deducting the photo size from the size of the view.
-
4:21
So let verticalSpace = size,
-
4:26
which is the argument we're passing in, .height-
-
4:29
photoImageView.frame.height.
-
4:35
To center the image vertically, we need to take this distance divided by 2,
-
4:40
and then set the photo to be offset from either end by this distance.
-
4:45
So we'll say let yOffset = verticalSpace/2.
-
4:50
In the event that the height of the image is the same as the height of the view
-
4:55
this value is 0, or let's say we have some weird edge case where the image is
-
4:59
actually larger than the height because I didn't double check all my code and
-
5:02
the math may be wrong, we might end up with a negative value.
-
5:05
So over here, let's use the max function to return a positive value or 0.
-
5:10
So instead of saying vertical space divided by 2,
-
5:14
we'll say the y offset is the maximum of 0 or
-
5:17
the vertical space divided by 2, which ever one is larger, okay.
-
5:21
Now that we have our y offset, we can set the constant values on the top and
-
5:25
the bottom constraints to these values.
-
5:28
So imageViewTopConstraint.constant = yOffset, and
-
5:33
imageViewBottomConstraint.constant = yOffset.
-
5:38
Let's see if this works.
-
5:40
So we'll call this method inside viewDidLoad at the end,
-
5:43
so we'll say updateConstraintsForSize.
-
5:46
And for the argument, we'll pass in the size of the view's bounds rectangle, so
-
5:51
view.bounds.size.
-
5:55
Okay, let's run this.
-
5:59
If we tap on an image now, so we have the photoViewerController, tap on this and
-
6:03
now there we go, it loads the image inside the scroll view perfectly centered.
-
6:08
Let's account for the horizontal offsets as well for
-
6:11
completeness just in case we have some weird image that's super narrow.
-
6:16
So let xOffset, and here I'm going to do it all
-
6:21
in one line cuz you know what I'm doing now, is the max(0,
-
6:28
or the size, let's put these in parenthesis,
-
6:33
(size.width- photoImageView.frame.width)/2).
-
6:40
And then once we have that, we'll say imageViewLeadingConstraint.constant
-
6:47
= xOffset, imageViewTrailingConstraint, if I can type
-
6:52
imageViewTrailingConstraint.constant = xOffset, there we go.
-
6:59
So run the app now and all the images should be zoomed in or zoomed out and
-
7:03
centered just like we want.
-
7:05
Now you can also zoom into the photo, let me show you that real quick, say Play.
-
7:10
We can also zoom into the photo because that's the behavior
-
7:13
the scrollView handles for us for free without any work.
-
7:17
So tap on an image, tap it again to go to the scrollView, and
-
7:20
then hold down the Alt or the Option key on your keyboard and
-
7:24
you'll notice that this changes your mouse into essentially a two figure tap.
-
7:28
If you now press somewhere down here, like when they're close together,
-
7:33
simulate your fingers being close together and then drag it apart,
-
7:37
there you go, you can zoom out, and then you can pan around the photo, perfect.
-
7:42
Now the reason we can do this is because we did not set a maximum zoom scale.
-
7:48
You'll notice that when we do this, there's some empty space above the photo.
-
7:52
And if we zoom in far enough over here, so
-
7:55
let's see, it looks like there's no photo actually on the screen.
-
8:01
There's no pictures, there's just a lot of empty space.
-
8:04
So in the next video, let's clean this up, make a few more small changes,
-
8:07
and finish up our app.
You need to sign up for Treehouse in order to download course files.
Sign up