diff --git a/HWPanModal.podspec b/HWPanModal.podspec index a92db9e..390dffe 100644 --- a/HWPanModal.podspec +++ b/HWPanModal.podspec @@ -8,7 +8,7 @@ Pod::Spec.new do |s| s.name = 'HWPanModal' - s.version = '0.8.5' + s.version = '0.8.6' s.summary = 'HWPanModal is used to present controller and drag to dismiss.' # This description is used to generate tags and improve search results. diff --git a/Sources/Controller/HWPanModalPresentationController.h b/Sources/Controller/HWPanModalPresentationController.h index 564d576..08ca0da 100644 --- a/Sources/Controller/HWPanModalPresentationController.h +++ b/Sources/Controller/HWPanModalPresentationController.h @@ -15,9 +15,12 @@ NS_ASSUME_NONNULL_BEGIN @interface HWPanModalPresentationController : UIPresentationController @property (nonatomic, readonly) HWDimmedView *backgroundView; +@property (nonatomic, readonly) PresentationState currentPresentationState; - (void)setNeedsLayoutUpdate; +- (void)updateUserHitBehavior; + - (void)transitionToState:(PresentationState)state animated:(BOOL)animated; - (void)setScrollableContentOffset:(CGPoint)offset animated:(BOOL)animated; diff --git a/Sources/Controller/HWPanModalPresentationController.m b/Sources/Controller/HWPanModalPresentationController.m index 552c4ec..eb3c44f 100644 --- a/Sources/Controller/HWPanModalPresentationController.m +++ b/Sources/Controller/HWPanModalPresentationController.m @@ -194,6 +194,11 @@ - (void)setScrollableContentOffset:(CGPoint)offset animated:(BOOL)animated { [self.handler setScrollableContentOffset:offset animated:animated]; } +- (void)updateUserHitBehavior { + [self checkVCContainerEventPass]; + [self checkBackgroundViewEventPass]; +} + #pragma mark - layout - (void)adjustPresentedViewFrame { @@ -327,6 +332,29 @@ - (void)configureViewLayout { self.containerView.userInteractionEnabled = [[self presentable] isUserInteractionEnabled]; } +#pragma mark - event passing through + +- (void)checkVCContainerEventPass { + BOOL eventPassValue = [[self presentable] allowsTouchEventsPassingThroughTransitionView]; + // hack TransitionView + [self.containerView setValue:@(eventPassValue) forKey:@"ignoreDirectTouchEvents"]; +} + +- (void)checkBackgroundViewEventPass { + if ([[self presentable] allowsTouchEventsPassingThroughTransitionView]) { + self.backgroundView.userInteractionEnabled = NO; + self.backgroundView.tapBlock = nil; + } else { + self.backgroundView.userInteractionEnabled = YES; + __weak typeof(self) wkSelf = self; + self.backgroundView.tapBlock = ^(UITapGestureRecognizer *recognizer) { + if ([[wkSelf presentable] allowsTapBackgroundToDismiss]) { + [wkSelf dismiss:NO mode:PanModalInteractiveModeNone]; + } + }; + } +} + #pragma mark - y position update - (void)snapToYPos:(CGFloat)yPos animated:(BOOL)animated { diff --git a/Sources/Presentable/HWPanModalPresentable.h b/Sources/Presentable/HWPanModalPresentable.h index d304fd6..0568100 100644 --- a/Sources/Presentable/HWPanModalPresentable.h +++ b/Sources/Presentable/HWPanModalPresentable.h @@ -199,14 +199,10 @@ typedef NS_ENUM(NSInteger, PresentingViewControllerAnimationStyle) { /** * 是否允许触摸事件透传到presenting ViewController/View。如果你有特殊需求的话(比如弹出一个底部视图,但是你想操作弹出视图下面的view,即presenting VC/View),可开启此功能 - * 注意开启此功能,拖拽指示器会默认隐藏,背景色alpha默认为0. * * Whether allows touch events passing through the transition container view. * In some situations, you present the bottom VC/View, and you want to operate the presenting VC/View(mapView, scrollView and etc), enable this func. * - * Note: When allows, the background view alpha = 0, and the drag indicator will be hidden. - * @return Default is NO. - * * Note: You SHOULD MUST dismiss the presented VC in the right time. */ - (BOOL)allowsTouchEventsPassingThroughTransitionView; diff --git a/Sources/Presentable/HWPanModalPresentationUpdateProtocol.h b/Sources/Presentable/HWPanModalPresentationUpdateProtocol.h index 357017a..7d202d2 100644 --- a/Sources/Presentable/HWPanModalPresentationUpdateProtocol.h +++ b/Sources/Presentable/HWPanModalPresentationUpdateProtocol.h @@ -15,6 +15,8 @@ @property (nonatomic, readonly) UIView *hw_rootContainerView; /// which view that your presented viewController's view has been added. @property (nonatomic, readonly) UIView *hw_contentView; +/// current presentation State +@property (nonatomic, readonly) PresentationState hw_presentationState; /** * force update pan modal State, short/long */ @@ -47,4 +49,9 @@ */ - (void)hw_panModalSetNeedsLayoutUpdate NS_SWIFT_NAME(panModalSetNeedsLayoutUpdate()); +/** + * 更新用户行为,比如事件穿透 + */ +- (void)hw_panModalUpdateUserHitBehavior NS_SWIFT_NAME(panModalUpdateUserHitBehavior()); + @end diff --git a/Sources/Presentable/UIViewController+PanModalDefault.m b/Sources/Presentable/UIViewController+PanModalDefault.m index a1daaee..2b599a4 100644 --- a/Sources/Presentable/UIViewController+PanModalDefault.m +++ b/Sources/Presentable/UIViewController+PanModalDefault.m @@ -56,10 +56,6 @@ - (UIViewAnimationOptions)transitionAnimationOptions { } - (CGFloat)backgroundAlpha { - // set the background alpha = 0 when allows touch events passing through - if ([self allowsTouchEventsPassingThroughTransitionView]) { - return 0; - } return 0.7; } @@ -72,13 +68,6 @@ - (nonnull UIColor *)backgroundBlurColor { } - (HWBackgroundConfig *)backgroundConfig { - // set the background alpha = 0 when allows touch events passing through - if ([self allowsTouchEventsPassingThroughTransitionView]) { - HWBackgroundConfig *config = [HWBackgroundConfig configWithBehavior:HWBackgroundBehaviorDefault]; - config.backgroundAlpha = 0; - return config; - } - return [HWBackgroundConfig configWithBehavior:HWBackgroundBehaviorDefault]; } diff --git a/Sources/Presentable/UIViewController+Presentation.m b/Sources/Presentable/UIViewController+Presentation.m index 84edf11..2c402b5 100644 --- a/Sources/Presentable/UIViewController+Presentation.m +++ b/Sources/Presentable/UIViewController+Presentation.m @@ -41,6 +41,11 @@ - (void)hw_panModalSetNeedsLayoutUpdate { [self.hw_presentedVC setNeedsLayoutUpdate]; } +- (void)hw_panModalUpdateUserHitBehavior { + if (!self.hw_presentedVC) return; + [self.hw_presentedVC updateUserHitBehavior]; +} + - (HWDimmedView *)hw_dimmedView { return self.hw_presentedVC.backgroundView; } @@ -53,4 +58,8 @@ - (UIView *)hw_contentView { return self.hw_presentedVC.presentedView; } +- (PresentationState)hw_presentationState { + return self.hw_presentedVC.currentPresentationState; +} + @end diff --git a/Sources/View/PanModal/HWPanModalContainerView.h b/Sources/View/PanModal/HWPanModalContainerView.h index 5e1e1ef..312097f 100644 --- a/Sources/View/PanModal/HWPanModalContainerView.h +++ b/Sources/View/PanModal/HWPanModalContainerView.h @@ -18,6 +18,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, readonly) HWDimmedView *backgroundView; @property (readonly) HWPanContainerView *panContainerView; +@property (nonatomic, readonly) PresentationState currentPresentationState; - (instancetype)initWithPresentingView:(UIView *)presentingView contentView:(HWPanModalContentView *)contentView; @@ -27,6 +28,8 @@ NS_ASSUME_NONNULL_BEGIN - (void)setNeedsLayoutUpdate; +- (void)updateUserHitBehavior; + - (void)transitionToState:(PresentationState)state animated:(BOOL)animated; - (void)setScrollableContentOffset:(CGPoint)offset animated:(BOOL)animated; diff --git a/Sources/View/PanModal/HWPanModalContainerView.m b/Sources/View/PanModal/HWPanModalContainerView.m index b1bab54..954484c 100644 --- a/Sources/View/PanModal/HWPanModalContainerView.m +++ b/Sources/View/PanModal/HWPanModalContainerView.m @@ -158,6 +158,11 @@ - (void)setNeedsLayoutUpdate { [self updateRoundedCorners]; } +- (void)updateUserHitBehavior { + [self checkBackgroundViewEventPass]; + [self checkPanGestureRecognizer]; +} + - (void)transitionToState:(PresentationState)state animated:(BOOL)animated { if (![self.presentable shouldTransitionToState:state]) return; @@ -428,6 +433,31 @@ - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { } } +- (void)checkBackgroundViewEventPass { + if ([[self presentable] allowsTouchEventsPassingThroughTransitionView]) { + self.backgroundView.userInteractionEnabled = NO; + self.backgroundView.tapBlock = nil; + } else { + self.backgroundView.userInteractionEnabled = YES; + __weak typeof(self) wkSelf = self; + self.backgroundView.tapBlock = ^(UITapGestureRecognizer *recognizer) { + if ([[wkSelf presentable] allowsTapBackgroundToDismiss]) { + [wkSelf dismiss:NO mode:PanModalInteractiveModeNone]; + } + }; + } +} + +- (void)checkPanGestureRecognizer { + if ([[self presentable] allowsTouchEventsPassingThroughTransitionView]) { + [self removeGestureRecognizer:self.handler.panGestureRecognizer]; + [self.panContainerView addGestureRecognizer:self.handler.panGestureRecognizer]; + } else { + [self.panContainerView removeGestureRecognizer:self.handler.panGestureRecognizer]; + [self addGestureRecognizer:self.handler.panGestureRecognizer]; + } +} + #pragma mark - getter - (id)presentable { diff --git a/Sources/View/PanModal/HWPanModalContentView.m b/Sources/View/PanModal/HWPanModalContentView.m index aecd718..a5835d6 100644 --- a/Sources/View/PanModal/HWPanModalContentView.m +++ b/Sources/View/PanModal/HWPanModalContentView.m @@ -44,6 +44,10 @@ - (void)hw_panModalSetNeedsLayoutUpdate { [self.containerView setNeedsLayoutUpdate]; } +- (void)hw_panModalUpdateUserHitBehavior { + [self.containerView updateUserHitBehavior]; +} + - (void)hw_panModalTransitionTo:(PresentationState)state animated:(BOOL)animated { [self.containerView transitionToState:state animated:animated]; } @@ -64,6 +68,10 @@ - (UIView *)hw_contentView { return (UIView *)self.containerView.panContainerView; } +- (PresentationState)hw_presentationState { + return self.containerView.currentPresentationState; +} + #pragma mark - HWPanModalPresentable - (UIScrollView *)panScrollable { @@ -112,9 +120,6 @@ - (UIViewAnimationOptions)transitionAnimationOptions { } - (CGFloat)backgroundAlpha { - if ([self allowsTouchEventsPassingThroughTransitionView]) { - return 0; - } return 0.7; }