View controller transitioning allowing self-sizing presented view controller to be dismissed by swiping down.
- iOS 10.0+
- Xcode 11+
- Swift 5.2+
HandyViewController is distributed with Swift Package Manager which is the only official distribution tool by Apple. You can add HandyViewController to your project from Xcode's File > Swift Packages > Add Package Dependency menu with its github URL:
https://github.com/mobven/HandyViewController.git
Basically, to achieve HandyViewController presentation, you set transitioningDelegate of your view controller to HandyTransitioningDelegate. There are two options while initializing HandyTransitioningDelegate:
Presented view controller must have necessary constraints (from top to bottom) to allow HandyViewController to calculate its height.
letcontroller= storyboard!.instantiateViewController(withIdentifier:"ViewController")lettransitioningDelegate=HandyTransitioningDelegate(from:self, to: controller)
controller.modalPresentationStyle =.custom
controller.transitioningDelegate = transitioningDelegate
present(controller, animated:true)presented: View controller presenting HandyViewController.
presenting: View controller being presented.
contentMode: Content mode of HandyViewController.
syncViewHeightWithKeyboard: When the keyboard is showed, view scrolls up with the keyboard.
maxBackgroundOpacity: Change background dim opacity, set zero to turn it off.
View controller displayed full screen with a small padding in the top.
letcontroller= storyboard!.instantiateViewController(withIdentifier:"ViewController")lettransitioningDelegate=HandyTransitioningDelegate(from:self, to: controller, contentMode:.fullScreen)
controller.modalPresentationStyle =.custom
controller.transitioningDelegate = transitioningDelegate
present(controller, animated:true)If presented view controller contains any UIScrollView (eg. UITableView, UICollectionView) that has no specifed content height, allow HandyViewController to calculate its size by:
overridefunc viewDidLoad(){
super.viewDidLoad()registerHandyScrollView(tableView)}HandyViewController provides swipe-to-dismiss feature with scroll events. To achieve this behavior, in your presented view controller:
extensionDetailsViewController:UIScrollViewDelegate{func scrollViewDidScroll(_ scrollView:UIScrollView){handyScrollViewDidScroll(scrollView)}func scrollViewWillEndDragging(_ scrollView:UIScrollView, withVelocity velocity:CGPoint,
targetContentOffset:UnsafeMutablePointer<CGPoint>){handyScrollViewWillEndDragging(scrollView, withVelocity: velocity)}}During usage we've faced content size calculation issues with presented view controllers containing UIStackView with fill distribution and alignment attributes. As a workaround to this issue HandyViewController adds an empty footer view to your stack view, which is invisible. You can achieve this by calling:
overridefunc viewDidLoad(){
super.viewDidLoad()registerHandyStackView(stackView)}- Allow view controller to interrupt swipe-to-dismiss.
- Tests in iPads.
- Swipe-to-dismiss indicator in top of the screen.
- iOS 13 modal presentation style for full-screen presented view controllers where presenting view controller frame decreased in background.
- Unit Tests.
Developed with 🖤 at Mobven



