Skip to content
HWPanModal presents controller from bottom and drag to dismiss, high customize. 实现任意形式的底部弹框;知乎、抖音弹出评论效果。
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.

HWPanModal 👍

HWPanModal is used to present controller and drag to dismiss.

Inspired by PanModal, thanks.



Basic Blur background Keyboard handle App demo


  1. Supports any type of UIViewController
  2. Seamless transition between modal and content
  3. Support two kinds of GestureRecognizer
    1. UIPanGestureRecognizer, direction is UP & Down.
    2. UIScreenEdgePanGestureRecognizer, you can swipe on screen edge to dismiss controller.
  4. Support write your own animation for presenting VC.
  5. Support config animation Duration, AnimationOptions, springDamping.
  6. Support config background alpha or blur background. Note: Dynamic change blur effect ONLY works on iOS9.0+.
  7. Show / hide corner, indicator.
  8. Auto handle UIKeyboard show/hide.

More config pls see HWPanModalPresentable.h declare.


  • Handle keyboard show&dismiss.
  • Touch event can response to presenting VC.


iOS 8.0+, support Objective-C & Swift.


KVOController - facebook

Because Objective-C KVO is hard to use, so I use KVOController = =



pod 'HWPanModal', '~> 0.2.9'

How to use

How to present from bottom

Your UIViewController need to conform HWPanModalPresentable. If you use default, nothing more will be written.

#import <HWPanModal/HWPanModal.h>
@interface HWBaseViewController () <HWPanModalPresentable>


@implementation HWBaseViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.

#pragma mark - HWPanModalPresentable
- (PanModalHeight)longFormHeight {
    return PanModalHeightMake(PanModalHeightTypeMaxTopInset, 44);

Where you need to present this Controller.

#import <HWPanModal/HWPanModal.h>
[self presentPanModal:[HWBaseViewController new]];

yeah! Easy.

Change state, scrollView contentOffset, reload layout

When You present you Controller, you can change the UI. Refer to UIViewController+Presentation.h.

  • Change the state between short and long form. call - (void)hw_panModalTransitionTo:(PresentationState)state;
  • Change ScrollView ContentOffset. call - (void)hw_panModalSetContentOffset:(CGPoint)offset;
  • Reload layout. call - (void)hw_panModalSetNeedsLayoutUpdate;

Custom Presenting VC Animation

Some guys want to animate Presenting VC when present/dismiss.

  1. Create object conforms HWPresentingViewControllerAnimatedTransitioning .

    @interface HWMyCustomAnimation : NSObject <HWPresentingViewControllerAnimatedTransitioning>
    @implementation HWMyCustomAnimation
    - (void)presentAnimateTransition:(id<HWPresentingViewControllerContextTransitioning>)transitionContext {
        NSTimeInterval duration = [transitionContext mainTransitionDuration];
        UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
        // replace it.
        [UIView animateWithDuration:duration delay:0 usingSpringWithDamping:0.8 initialSpringVelocity:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
            fromVC.view.transform = CGAffineTransformMakeScale(0.95, 0.95);
        } completion:^(BOOL finished) {
    - (void)dismissAnimateTransition:(id<HWPresentingViewControllerContextTransitioning>)transitionContext {
        NSTimeInterval duration = [transitionContext mainTransitionDuration];
        UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
        // replace it.
        [UIView animateWithDuration:duration animations:^{
            toVC.view.transform = CGAffineTransformIdentity;
  2. Overwrite below two method.

    - (BOOL)shouldAnimatePresentingVC {
        return YES;
    - (id<HWPresentingViewControllerAnimatedTransitioning>)customPresentingVCAnimation {
        return self.customAnimation;
    - (HWMyCustomAnimation *)customAnimation {
        if (!_customAnimation) {
            _customAnimation = [HWMyCustomAnimation new];
        return _customAnimation;


  1. Clone this git.
  2. open the terminal, go to the Example Folder.
  3. pod install --verbose
  4. Double click HWPanModal.xcworkspace, and run.

Contact Me

Heath Wang


HWPanModal is released under a MIT License. See LICENSE file for details.

You can’t perform that action at this time.