Need help with HWPanModal?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.

About the developer

HeathWang
591 Stars 111 Forks MIT License 261 Commits 4 Opened issues

Description

HWPanModal presents controller from bottom and drag to dismiss, high customize. iOS13 default modalPresentationStyle. 任意形式的底部弹框动画;头条、知乎、抖音弹出评论效果;地图浮层,iOS13 present默认模态效果。

Services available

!
?

Need anything else?

Contributors list

HWPanModal 👍

codebeat badge

HWPanModal is used to present controller and drag to dismiss. Similar with iOS13 default present Modal style.

Inspired by PanModal, thanks.

中文文档说明

My another project for pop controller:HWPopController

Special Thanks

Special Thanks to JetBrains! I use AppCode IDE to develop my open source project.

Snapshoot

Basic Blur background Keyboard handle App demo

Index

Features

  1. Supports any type of
    UIViewController
    to present.
  2. Support View which inherit from
    HWPanModalContentView
    to present.
  3. Seamless transition between modal and content.
  4. Support two kinds of dismissal gestureRecognizer interaction
    1. Pan gesture direction up&down
    2. Pan gesture direction right, you can swipe on screen edge to dismiss controller.
  5. Support write your own animation for presenting VC.
  6. Support config animation
    Duration
    ,
    AnimationOptions
    ,
    springDamping
    .
  7. Support config background alpha or
    blur
    background. Note: Dynamic change blur effect ONLY works on iOS9.0+.
  8. Show / hide corner, indicator.
  9. Auto handle UIKeyboard show/hide.
  10. Hight customize indicator view.
  11. Touch event response can pass through to presenting VC.
  12. Config presented view shadow style.

More config pls see HWPanModalPresentable.h declare.

What's different between UIViewController and HWPanModalContentView to present ?

From version 0.6.0, this framework support using

HWPanModalContentView
to present from bottom, that means we can add subview(inherit from
HWPanModalContentView
) to the target view that you want to show.

The different is

HWPanModalContentView
is just a view, and support some animations, unlike present ViewController, you will got ViewController life circle, and navigation stack.

HWPanModalContentView
limit: * Currently not support screen rotation. * Not support edge horizontal pan to dismiss. * Not support customize presentingVC animation. (There is no presentingVC for view).

TODO

  • [x] Handle keyboard show&dismiss.
  • [x] High customize indicator view.
  • [x] Edge Interactive dismissal can work on full screen and configable distance to left edge.
  • [x] Touch event can response to presenting VC, working on it.
  • [x] Strip the presented view container view, make it can use directly.

Compatibility

iOS 8.0+, support Objective-C & Swift.

Installation

CocoaPods

pod 'HWPanModal', '~> 0.6.0'

How to use

How to present UIViewController from bottom

Your UIViewController need to conform

HWPanModalPresentable
. If you use default, nothing more will be written.
#import 
@interface HWBaseViewController () 

@end

@implementation HWBaseViewController

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

#pragma mark - HWPanModalPresentable

  • (PanModalHeight)longFormHeight { return PanModalHeightMake(PanModalHeightTypeMaxTopInset, 44); } @end

Where you need to present this Controller.

#import 
[self presentPanModal:[HWBaseViewController new]];

yeah! Easy.

Change state, scrollView contentOffset, reload layout. IMPORTANT!

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;
* Note: When your scrollable changed it's contentSize, you MUST reload the layout.

Custom Presenting VC Animation

Some guys want to animate Presenting VC when present/dismiss. 1. Create object conforms

HWPresentingViewControllerAnimatedTransitioning
.
```Objective-C

@interface HWMyCustomAnimation : NSObject

@end

@implementation HWMyCustomAnimation

  • (void)presentAnimateTransition:(id)transitionContext { NSTimeInterval duration = [transitionContext transitionDuration]; 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)transitionContext { // no need for using animating block. UIViewController *toVC = [context viewControllerForKey:UITransitionContextToViewControllerKey]; toVC.view.transform = CGAffineTransformIdentity; }

@end

```

  1. Overwrite below two method.

    - (PresentingViewControllerAnimationStyle)presentingVCAnimationStyle {
        return PresentingViewControllerAnimationStyleCustom;
    }
    
    
    • (id)customPresentingVCAnimation { return self.customAnimation; }

    • (HWMyCustomAnimation *)customAnimation { if (!_customAnimation) {

        _customAnimation = [HWMyCustomAnimation new];

      } return _customAnimation; }

Custom your own indicator view

You just need to create your own UIView, then adopt

HWPanModalIndicatorProtocol
.

In your presented controller, return it:

- (nullable UIView  *)customIndicatorView {
    HWTextIndicatorView *textIndicatorView = [HWTextIndicatorView new];
    return textIndicatorView;
}

Here is

HWTextIndicatorView
code:
@interface HWTextIndicatorView : UIView 

@end

@interface HWTextIndicatorView () @property (nonatomic, strong) UILabel *stateLabel; @end

@implementation HWTextIndicatorView

  • (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) {
      // init the _stateLabel
      [self addSubview:_stateLabel];
    } return self; }
  • (void)didChangeToState:(HWIndicatorState)state { switch (state) {

      case HWIndicatorStateNormal: {
          self.stateLabel.text = @"Please pull down to dismiss";
          self.stateLabel.textColor = [UIColor whiteColor];
      }
          break;
      case HWIndicatorStatePullDown: {
          self.stateLabel.text = @"Keep pull down to dismiss";
          self.stateLabel.textColor = [UIColor colorWithRed:1.000 green:0.200 blue:0.000 alpha:1.00];
      }
          break;

    } }

  • (CGSize)indicatorSize { return CGSizeMake(200, 18); }

  • (void)setupSubviews { self.stateLabel.frame = self.bounds; }

@end

How to use HWPanModalContentView

You should always inherit from

HWPanModalContentView
.
HWPanModalContentView
conforms
HWPanModalPresentable
like the way using UIViewController.
@interface HWSimplePanModalView : HWPanModalContentView

@end

@implementation HWSimplePanModalView

  • (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) {

      // add view and layout.

    }

    return self; }

// present it. HWSimplePanModalView *simplePanModalView = [HWSimplePanModalView new]; [simplePanModalView presentInView:nil];

Example

  1. Clone this git.
  2. open the terminal, run
    pod install
  3. Double click HWPanModal.xcworkspace, and select a target to run.
I have wrote both pure
Objective-C
&
Swift
Examples , for most of the framework functions.

Contact Me

Heath Wang [email protected]om

WeChat

Change Log

Click Me

License

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

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.