使用 UIScreenEdgePanGestureRecognizer 扩展 PKRevealController

Extending PKRevealController with UIScreenEdgePanGestureRecognizer's

我正在尝试使用 PKRevealController,它在前视图控制器上带有 UIPanGestureRecognizer,因此平移会显示左视图控制器。我不想仅在从屏幕边缘滑动时才进行平移。我知道我必须使用 UIScreenEdgePanGestureRecognizer 而不是 UIPanGestureRecognizer。当显示左视图控制器时,我还需要前视图控制器上的 UIPanGestureRecognizer,这样用户就可以向后滑动前视图控制器。

这样做并不容易,所以我决定子 class PKRevealController 并添加新的 UIScreenEdgePanGestureRecognizer 并重写一些方法来达到这个效果。但是 none 的处理手势的方法是在 class 扩展中声明的。所以我无法在我的超级 class.

中访问它们

最终决定对PKRevealController的源代码进行修改。我进行了所有更改,并且它按我想要的方式工作。 但我知道我们应该只继承class第三方框架并扩展它们的功能,而不是直接更改源代码。但我找不到任何解决方法。

在不对 PKRevealController 源代码本身进行更改的情况下是否有任何解决方法。任何建议都会非常有帮助。

有趣的是,几周前我遇到了同样的问题。我没有找到一种简单且完全干净的方法来解决这个问题,但我确实设法通过子类化 PKRevealController 和适度 "invasive" 来解决问题(这并不意味着它不能打破库的未来更新)。

所以,我所做的是创建自己的 UIScreenEdgePanGestureRecognizer 并将其存储在 属性 中(这里的所有内容都在我的 PKRevealController 子类中):

@property (nonatomic, strong) UIScreenEdgePanGestureRecognizer *screenEdgePanGestureRecognizer;

init中:

// use screen edge pan gesture recognizer instead of normal built-in pan gesture recognizer
self.recognizesPanningOnFrontView = NO; // disable built-in pan gesture recognizer

self.screenEdgePanGestureRecognizer = [[UIScreenEdgePanGestureRecognizer alloc] initWithTarget:self
                                                                                        action:@selector(didRecognizePanGesture:)];
self.screenEdgePanGestureRecognizer.maximumNumberOfTouches = 1;
self.screenEdgePanGestureRecognizer.edges = UIRectEdgeLeft;

注意,动作选择器 (didRecognizePanGesture:) 是由超类实现的。

然后,为了安装我自己的手势识别器而不是内置的,我覆盖了 updatePanGestureRecognizerPresence:

// overwritten to use our custom screen edge pan gesture recognizer!
- (void)updatePanGestureRecognizerPresence
{
    if (![self.frontView.gestureRecognizers containsObject:self.screenEdgePanGestureRecognizer]) {
        [self.frontView addGestureRecognizer:self.screenEdgePanGestureRecognizer];
    }
}

并且由于我们正在访问 PKRevealController 的一些非公开声明的内容(正如您自己注意到的那样),我们需要使其可见(在您的 @implementation 之前):

// make private superclass stuff visible to be able to use a screen edge gesture recognizer
@interface PKRevealController ()
@property (nonatomic, strong, readwrite) PKRevealControllerView *frontView;
- (void)didRecognizePanGesture:(UIPanGestureRecognizer *)panGestureRecognizer;
@end

它工作得很好,它是我能找到的最好的方法,而无需 fork PKRevealController 本身。它确实有点脆弱,但由于我可以完全控制何时升级 PKRevealController 这对我来说没问题。

当然,你能做的最好的事情就是 fork PKRevealController,实现使用屏幕边缘识别器的选项(或者使整个手势架构更具可扩展性)并提交一个 pull要求。 :-)

我找到了另一个正在开发的应用程序抽屉,它提供从边缘平移到动画的所有强大功能。这是 link 到 https://github.com/mutualmobile/MMDrawerController 。升级您的项目以使用新的 DrawerController 或 Reveal 控件不会花费太多时间。

主要是扩展此框架以添加更多功能很容易,并且团队正在积极为项目做出贡献。