The aim of this post is just to explain how simple is to make a drowdown view controller using Autolayout (… and a few lines of code also). But believe be, the magic is done by Autolayout. At the end you will have a view controller that will allow to drop down the upper view:
Setup the project
Create a brand new Single View Application project:
Be sure that Language is swift:
In the default View controller add two views, one in the top-half and the other in the bottom-half. Finally add a button in the middle of two views:
I have added some color in the view components just for better clarification.
Autolayout
Top subview. Add the following 5 constraints:
Bottom subview. Add the following 4 constraints:
Button. Add the following 3 constraints:
Button – Bottom subview. For the following constraint do not forget select Top subview and Button.
And apply the following constraint:
Autolayout is giving to you a warning because he excepts that Button and Top subview would be bottom alligned.:
Our intention is leave the buttom in the middle of two views, so we have to update constraint:
… and a few lines of code
Outlets
@IBOutlet weak var btnFoldButton: UIButton! @IBOutlet weak var cnsUpperViewHeight: NSLayoutConstraint!
Now link outlets:
- btnFoldButton to the button
- cnsUpperViewHeight to the Top view height constraint.
Add pan gesture recognizer to Button:
override func viewDidLoad() { super.viewDidLoad() ... self.btnFoldButton.addGestureRecognizer(UIPanGestureRecognizer.init(target: self, action: "panDetected:")) }
What we do in the gesture recognizer is just calculate new value for cnsUpperViewHeight constraint, the hard work is performed by autolayout.
class ViewController:UIViewController { var heightUpperView:CGFloat = 0.0 ... func panDetected(recognizer: UIPanGestureRecognizer){ if(recognizer.state == UIGestureRecognizerState.Began){ heightUpperView = self.cnsUpperViewHeight.constant } let point:CGPoint = recognizer.translationInView(self.btnFoldButton.superview) let newHeight = heightUpperView + point.y if(newHeight >= UIScreen.mainScreen().bounds.height * 0.15 && newHeight <= UIScreen.mainScreen().bounds.height * 0.66){ cnsUpperViewHeight.constant = newHeight } } ...
Finally
Let’s make some make up, just adding some picture at the top subview and a map at the bottom view.
For the picture and the map add the following constraints:
For the map do not forget the import MapKit in the view controller code:
Finally run the project:
Pan the button and you will see how top view is compressed, giving more room for bottom view.
You can also download the sample project from gitHub.
Variant
If what you really want is just shift the upper view and avoid compress effect on the top view, just remove the top constraint on the picture that is placed at the top subview:
This will be what you get:
Useful links:
- Cocoa control link to this control.
- Ray Wenderlich autolayout videotutorials.
- Component page.