Hey guys this is Caleb with Debb slopes and in this video we're going to create an animated view that
slides up.
We already created The View earlier but we're going to animate it up.
We're going to animate it down.
And we're also going to add a spinner and a UI label to show download progress for those photos we're
going to download in later video.
So let's go ahead and let's look at where we were at last time.
Here's our simulator and in the last video we set it up so that you can drop a pin and the map automatically
centers and animate to wherever that pin is dropped.
When you drop a new pin it removes the old pin and adds a new one.
Then when you click the center button it centers you back on your current location.
Pretty cool.
And let's go ahead and pull open our tax code project to get started.
So in this lesson we are going to animate that view so that it is showing.
But before we do that we need to actually create some Iby outlets first.
So let's go into our main storyboard.
Let's open up the assistant editor make sure everything is visible and make sure this is on automatic.
I'm also going to close this so I have some extra room.
And do you remember that we hid a little of you down here.
It's very small it's out of the way but it's really important actually.
So if you look you'll notice that this has a constraint of the trailing space the leading space as well
as the top space is pinned to the bottom layout of the screen and the top spaces is also pinned to the
map view.
But you know what for what we want to do that's not going to work.
We need to get rid of this top space to bottom lay out and we actually need to pin the bottom of the
view to the bottom layout.
So if I add that constraint you'll see that it actually is still doing the same thing.
Oh you know what.
That's because this has a height of zero.
We need to give it a height of 1 because basically if it has a height of zero the top and the bottom
are exactly the same.
Let's try that again.
A constraint.
Let's make it zero from the bottom.
And when we add it you'll notice that the bottom space snaps to the Super view just like it's supposed
to which is awesome.
The top space goes to the bottom of the map view.
And if you click on the map view you'll see that the bottom space connects to the view which is this
one right here.
That's exactly what we want.
Because basically what we're going to do and I don't know if you know you can do this but we're going
to animate this constraint.
That's kind of an easy way for us to do this animation is just to simply animate the constraint.
This button is already in place and if you look it's bottom space is paying attention to the bottom
layout.
We actually need to change that.
So let's do that by going head and let's set this so that it is up here.
Let's pin it again.
But let's turn off constrained to margins and let's add one constraint.
Now you'll notice the bottom space now is to the view.
So when the view slides up the button will move as well by having constrained to margins that pays attention
to the actual margins of the screen and we don't want that so let's go ahead and let's create a an IP
outlet for our bottom constraint here and you'll look I found the right one by clicking down on the
bottom.
And this is the view up top and not view dot bottom constraint.
And so to create an IP outlet I'm going to right click drag and then I'm going to name this map view
map view bottom constraint.
Awesome.
OK that looks pretty good.
And you know what I'm also going to create a constraint or sorry an outlet for this view because we're
going to need to add this view not only as a view that we can access but we're going to add some views
on top of it.
So let's just call this a pull up view.
OK so now we can access both the map views bottom constraint as well as this current little tiny skinny
view here.
OK.
So let's go set this up so that we can animate it and show it on the screen.
To do that we're basically going to write two little functions and we're going to call them to animate
up as soon as we drop a pin and then we're going to basically create a swipe gesture to animate it down
when we swipe on the view.
So let's go ahead and do that beneath add double tap our function.
Go ahead and write phunk animate view up and inside this function we're first going to set the constraint
to have a new constant.
Now it's currently at zero meaning that wherever it's constrained that is it's kind of its base at home.
So we're going to modify the constraint to move up a certain amount.
So to do that go ahead and call map view bottom constraint constant and that is actually going to be
equal to 300.
We're going to make it move up 300 to give us a nice big view that we can load some images into.
But you know what.
Just calling.
This is not good enough.
We actually need to call a function that is a part of the view.
And it's called lay out if needed.
So let me go ahead and call that self dot view.
Lay out if needed.
And if you look at the information on this it says that it lays out the sub views immediately and it
forces the layout of sub views before drawing.
So we have updated the constant of this constraint and layout if needed is going to redraw everything
and show what has changed.
But we want it to be animated.
We don't want it to just all of a sudden 300.
So to do that we can just simply call you I view that animate with duration and you know let's move
that up so we have a little bit of space.
Let's do this over 0.3 seconds.
And for the animations closure go ahead and just press enter and we're going to move out if needed.
Inside that closure I just cut it and pasted it inside the closure of you I've you animate with the
station.
So this alone should animate our view up.
And like I said earlier we're going to animate this when we drop a pin.
So let's go call it where we drop our pin right here drop pin down to sew beneath remove pin call animate
view up and I want to go see if it worked let's go try it build and run find your simulator and as soon
as it pulls up we should be able to drop a pin and animate our view.
Let's see how we did.
OK so we've got ourselves a problem here.
It looks like our view is now covering our screen so we need to go do some fixes to our auto layout.
Let's think of let's think about what we have done wrong.
Top basis is pinned to the top leading and trailing are pinned to the Super view bottom space is pinned
to the pull up view.
OK that looks good.
Now let's look at the pull up view bottom space is good.
Oh you know what.
That's good.
Yes should be to the supervisor of leading spaces they're trailing spaces there.
That's good.
Top space is to the map view and the top space to the button is also there.
That looks fine.
So you know what I think the issue is that in the map view itself does not have a fixed height and the
pull up view does not have a fixed height so it's not sure how tall or short it should make either of
these.
So I think instead what we're going to do I'm going to I'm going to make some changes here on the fly.
Let's go ahead and go back into our view controller sorry I open the assistant editor there and I pulled
open the view controller.
I'm going to get rid of this constraint here.
And I'm also going to go in and find that constraint which is here or not here maybe it's let's see
well it's this one here if I right click.
Yet still referencing that so I'm going to get rid of it so we don't have a crash and instead of doing
that I think what I'm going to do is I'm going to look for pull up view top and I'm going to actually
animate that constraint.
OK.
No that's not true.
You know what I should do I should give it a constraint for height and then we should animate the height
constraint.
Let's do that.
So I'm going to go ahead and give this a height of 1.
OK.
That looks great.
And now when I come in here I can find that constraint by going into the constraints for pull up view.
And here's our height constraint we can right click and drag and I can call this pull up view height
constraint.
All right there we go.
So now what I can do is I can go back and fix that function that we wrote in Matt Visi animate view
up let's find it.
There it is.
OK so obviously you can't find that anymore but we're going to call pull up view height constraint and
we're going to change it from one all the way to 300.
So when I build and run this now based on our changes we have a height constraint Now that's keeping
this out one pixel.
And then we're modifying it as we open that little tray.
Now it looks like our button is out of place now we'll fix that.
But for now let's double click and see if it animates.
All right.
Awesome so it drops a pin it animates up.
Great.
Yeah that's awesome That's exactly right.
That's perfect.
So let's fix our button then really quickly it looks like we no longer have a bottom constraint.
So let's click the pin button.
Let's pin it to the bottom and you know what it's actually going to pin it perfectly 20 to the pull
up view so that when we slide it up the button is going to move with the map view.
Let's go ahead and build and run it again let's just make sure that we fix that problem.
There we go.
OK great.
Let's drop a pen and see if it moves with it.
Beautiful.
OK good.
So the pin drops the button moves and the view animates up.
That's exactly what we want.
But now we need to basically set it up so that when we swipe down on this view it hides.
That's just a pretty common interaction and it's really easy actually to add such a thing.
So I'm going to put this beneath and double tap.
I'm going to type func and swipe and in add swipe what I'm going to do is I'm going to create a UI swipe
gesture recognizer.
This allows us to take note of a swipe gesture on the screen either up down left or right.
So go ahead and type let swipe and that's going to be you swipe gesture recognizer and just like the
tap gesture it has a target and an action so the target of course is self and the action is going to
be animate view down.
But we don't have that yet.
We haven't written the function to animate the view down.
To do that.
Go ahead and just write it really quickly it's just like the one above phunk animate view down.
And then we're going to call the constraint.
We're going to set the constant to zero so that it's totally hidden.
And then we're going to animate layout if needed.
Go ahead and type you I view that animate with the ration 0.3.
And in the closure layout if needed I'm moving a little faster because we've already done this.
But for the selector that's exactly what we need.
So type hash tag selector hey.
And in the parentheses.
Go ahead and call animate view down.
OK.
And that will show up nice in green because we're calling it like calling the function there whenever
the selector is done.
Now it's going to give us an error saying that it's not exposed to Objective-C.
Click Fix.
It adds that in just like it needed to with the other function dropped pin.
That's fine.
Now we need to set the settings for Swype.
So let's go ahead and call Swype direction.
And you can pull from an enum called you I swipe gesture recognizer direction select down and that will
allow us to swipe down.
Now of course just like the tap gesture it's not really any use to us unless we actually add the gesture
recognizer So we're going to add it to the pull up view.
So call pull up view and then add gesture recognizer and pass that swipe.
OK so when we add the swipe we can just swipe down and it will animate the view down.
So you know what we're actually going to add this in the same spot that we add.
The view here when we animate it up we're going to add the swipe.
OK.
So it doesn't really make sense to add it until then because as soon as it's visible that's when we
should be able to swipe it.
So let's go ahead and build and run let's see if what we added here makes a cool interaction.
We should be able to double tap showed the view like before but this time when we swipe down it should
animate down and hide out of the way.
So double click is our view and let's swipe down.
Nothing.
Oh no it did.
It just was a little delay.
Let's try it again shows and then we swipe and hides.
So cool.
All right.
So that's perfect.
Now let's go ahead and let's add the spinner and let's add the label so that we can give the user a
clue of what's happening the label will update saying 1 out of 40 images downloaded 2 out of 40 images
downloaded.
It'll update every time so the user has a clue of what's going on and the spinner just indicates that
something is loading.
So in order to do this we're actually going to create some variables appear at the top and then we will
instantiate them as soon as we need them.
This makes it easy for us to manage and remove them at will.
Instead of having to cycle through all of the sub views and a certain view and then remove the one with
a certain tag it's much easier just to create an instance of it and then remove that instance.
So let's create a spinner by typing var spinner.
And that's going to be of type UI activity indicator view.
Now we're going to put a question mark because we do not have a value yet for this we're going to instantiate
it later on.
And then after this go ahead and type var label or we'll let's let's be more descriptive.
Progress label of type I label.
All right.
So we have these.
Now let's go instantiate them with some functions.
We're going to call these functions as soon as we need these labels.
And so let's go ahead and do this actually beneath animate view down.
Let's go ahead and write phunk add spinner.
And the spinner of course is going to be instantiated at this point.
So type spinner equals UI activity indicator view and give it a parentheses there to instantiate it.
Make an instance of it.
Now for the spinner there are a couple properties that we have to set.
We have to give it a center a style a color and we have to start animating.
So go ahead and do that by typing spinner dot center.
And we want this let's think about where we want it we want it to be right in the center of this view
that's animated up.
So to do that we're going to go ahead and type C.G. point because remember that's the center of a spinner
you can't see it until I'm done typing this.
But the center is of type C-g pointed to a specific point on our screen and the C-g point that we're
going to use is going to be called using an X and a Y value.
Now I think that it would be great if we could get the screen size and then divide that by two to get
the middle.
But we don't really have a way of monitoring that.
So I'm actually going to create another property up here called screen size.
So go ahead and type bar screen size like that and it's going to be equal to you I screen main dot dot
bounds.
OK.
Now that's going to be our screen and we can use this rectangle to divide our screen in half and find
the middle.
So for our center go ahead and type screen size with the width of the screen divided by two and that
will put the start of the frame right here in the middle.
But we actually need to move it back.
Now something we need to do to move it back is to basically cut the spinner in half and move it half
of how wide it is and to do that we can go ahead and just type minus spinner frame that width divided
by divided by two.
Now if you know anything about the order of operations you know we may have some problems here so let's
go ahead and put these division operations inside of their own parentheses so that we are actually subtracting
the proper values.
This way it's going to move it to be exactly in the center of our frame.
Now we're missing a y value here but we already know that our spinner should be in the center.
This is 300 tall so the center should be 150.
If that's the middle of 300 we should put it at 150.
All right cool.
Now that looks great we have a center and we're getting an error.
So what is the problem.
OK so our spinner is optional at that time but as soon as we instantiate it it will have a frame.
So we're going to go ahead and force unwrap it by putting it in parentheses and then unwrapping it.
That's great.
Now let's go ahead and let's give it a style spinner activity indicator view style.
We're going to do white large.
This makes a nice big spinner.
Let's give it a color because we don't want it to just be white because the background is white.
So let's go ahead and give it a color literal and let's set the color literal to be dark gray.
Awesome.
And let's go ahead and get started animating spinner dot start animating.
So as soon as this is done it will be spinning it will look nice.
The only issue though is just like everything else.
It's no good unless we have actually added it to our screen and we have not yet.
So we need to go ahead and do that.
Let's add it to our pull up view so go ahead and type pull up view add sub view and we're going to add
the spinner.
So whenever we call add spinner it will be added right in the center it'll be gray and it'll be animating.
Of course we need to unwrap it because it was optional.
And now let's add it when we drop a pin we swipe up.
Let's go ahead and add a spinner and let's go build and run to see if this worked.
I think we're going to have to call this video quits.
We'll add the label in the next video as well as some other stuff we'll have to we'll have to rearrange
some of these things when we add the collection view.
But this will at least give us a clue as to whether we're doing this right with spinner.
So let's go ahead and double tap and look at that perfect a spinner right in the center.
That looks awesome.
But you'll notice if I click another pin there's another spinner there's another spinner another spinner
and soon you can't really tell if there's a spinner there or not.
That's because we're adding one every time we're going to write a function in the next video that will
remove the spinner and add a new one every time that we click this so that we don't have a multitude
of spinners that will be a much much much better way of doing that.
So in the next video we're going to add are you I label.
We're going to add our collection view.
We're going to just basically make it so that this is a nice very smooth user interface without any
extra components or anything like that.
So great job with this video and we'll see in the next one.