this is what I like to achieve:
I want to perform a slide up animation where a user can slide a UIView2 up, and the UIView2 will stop half-way on the screen.
I know how to present a UIViewControler modally via a UIButton action like so:
[self presentViewController:newController animated:NO completion:nil];
I also know you need this type of code for animations:
[UIView animateWithDuration:0.5f animations:^{
[self.customView layoutIfNeeded];
} completion:^(BOOL finished) {
}];
However, I'm not sure how to achieve this with UIViews, especially since I use AutoLayout for my project and I use constraints to easily support multiple screen sizes.
How can I achieve this without breaking AutoLayout and the constraints I have set up?
Thanks
What I typically do in this situation is the following.
Add two constraints to your scene. One where
UIView2
is aligned to the bottom ofUIView1
. The second, where it's aligned center ofUIView1
(you'll want to ctrl+drag between the views to add the constraints appropriately). These constraints will initially conflict with one another, and that's fine.Add
IBOutlet
s to your view controller for theNSLayoutConstraints
and assign the two constraints we've created to thoseIBOutlet
s.Set the constraint priority on your initial condition to 999 (i.e. constraint priority on align to bottom should be 999). Set the constraint priority on the destination constraint to 998 (i.e. constraint priority on align center is 998). You'll now see that these constraints will no longer conflict. This is because the priority on one constraint overrides the other.
You may see where this is headed now. So when you want to animate
UIView2
between the constraints, swap the priorities and animate!Code:
To enable panning and using that to initiate your animation add a Pan Gesture Recognizer to your view controller. Ctrl+drag from
UIView2
to the Pan Gesture Recognizer and set it as agestureRecognizer
. Now when you drag onUIView2
, you'll be able to receive pan events.Add an IBAction to handle the pan:
Ctrl+drag from the pan gesture recognizer to the view controller and set
onPan:
as the sent action.sender
is actually the pan gesture recognizer itself. So we'll be able to fill out this method to handle a pan and haveUIView2
follow under the user's finger and then initiate the animation when they let go.Let's start filling out the code:
If you run with this code, and drag your finger over
UIView2
, you'll see output like this:Notice that the values are constantly increasing. We'll want the incremental amount. Notice the state in the log. State (1) is drag start. State (2) is drag changed. State (3) is drag ended. Using this information, we can calculate the delta.
Add a
CGPoint
property to your view controller and add UIView2 as an IBOutlet as well:Finally, let's fill out the final form of our pan method:
This should get you well on your way. You may want to look at tweaking the UIView animation on the constraints a bit based on the pan gesture's
velocityInView:
method, but that I'll leave as an exercise.