我的应用程序中到处都有自定义的后退按钮,看起来导航控制器不喜欢它。
因此,我希望 iOS7 滑动返回手势与我的自定义后退按钮一起使用。搜索并尝试了不同的方法,但似乎没有一种是有希望的。我能得到的最接近的是 http://keighl.com/post/ios7-interactive-pop-gesture-custom-back-button/。但是,现在当我继续推动和弹出导航堆栈时,一段时间后堆栈中的 rootViewController 停止响应任何触摸。
有什么建议吗?
子类化UINavigationController,就像keighl建议的那样,是imo的正确方法。但是他缺少对根视图控制器的检查,以避免在根视图上执行手势时冻结。这是带有附加检查的修改版本:
CBNavigationController.h:
#import <UIKit/UIKit.h>
@interface CBNavigationController : UINavigationController <UIGestureRecognizerDelegate, UINavigationControllerDelegate>
@end
CBNavigationController.m:
#import "CBNavigationController.h"
@interface CBNavigationController ()
@end
@implementation CBNavigationController
- (void)viewDidLoad
{
NSLog(@"%s",__FUNCTION__);
__weak CBNavigationController *weakSelf = self;
if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)])
{
self.interactivePopGestureRecognizer.delegate = weakSelf;
self.delegate = weakSelf;
}
}
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
NSLog(@"%s",__FUNCTION__);
if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)])
self.interactivePopGestureRecognizer.enabled = NO;
[super pushViewController:viewController animated:animated];
}
#pragma mark UINavigationControllerDelegate
- (void)navigationController:(UINavigationController *)navigationController
didShowViewController:(UIViewController *)viewController
animated:(BOOL)animate
{
NSLog(@"%s",__FUNCTION__);
// Enable the gesture again once the new controller is shown AND is not the root view controller
if (viewController == self.viewControllers.firstObject)
{
if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)])
self.interactivePopGestureRecognizer.enabled = NO;
}
else
{
if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)])
self.interactivePopGestureRecognizer.enabled = YES;
}
}
@end
目标-C
我遇到了同样的问题,这是我的解决方案:在自定义导航控制器中,如MYNavigationController
,因为您将手势委托设置为导航控制器,因此可以在此处添加委托方法:
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{
if (self.viewControllers.count>1) {
return YES;
}
return NO;
}
然后,当它在根视图中时,它将停止弹出操作控制器并避免冻结行为。
即使我也有同样的问题,我也通过修改您引用的链接中提供的代码来修复它。现在我的屏幕很少冻结,仍然找到永久修复。
@implementation PPNavigationController
-(void)viewDidLoad
{
//[super viewDidLoad];
// Do any additional setup after loading the view.
__weak PPNavigationController *weakSelf = self;
if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)])
{
self.interactivePopGestureRecognizer.delegate = weakSelf;
self.delegate = weakSelf;
}
}
-(void)navigationController:(UINavigationController *)navigationController
didShowViewController:(UIViewController *)viewController
animated:(BOOL)animate
{
// Enable the gesture again once the new controller is shown
if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)])
self.interactivePopGestureRecognizer.delegate = viewController;
}
Don't use this method
//-(void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated{
//}
这是我对这里提出的类似问题的回答
您可以使用一个小技巧来使本机手势正常工作。创建 UINavigationItem
的子类,然后覆盖leftBarButtonItems
方法:
- (NSArray*)leftBarButtonItems
{
return nil;
}
现在将此类用于具有自定义左UIBarButtonItem
的项目。手势有效!这是因为UINavigationController
认为没有剩余的物品并启用了该手势。您仍然可以通过 leftBarButtonItem
属性访问自定义项。
这里有一个简单的 Swift 子类,你可以使用它UINavigationController
,我改编自@weak的答案。不需要实现UIGestureRecognizerDelegate
,因为导航委托的navigationController(_:didShow:animated:)
处理启用和禁用弹出手势的工作。
情节提要或代码中使用此子类比在 nav 控制器中嵌入的其他控制器中执行一次性禁用更容易。
import UIKit
@objc class LWNavigationController : UINavigationController,
UINavigationControllerDelegate {
override func viewDidLoad() {
self.delegate = self
}
override func pushViewController(_ viewController: UIViewController,
animated: Bool) {
// Disable this gesture while animating a push.
self.interactivePopGestureRecognizer?.isEnabled = false
super.pushViewController(viewController, animated: animated)
debugPrint("------(#function) (viewController)------")
}
// MARK: - UINavigationControllerDelegate
func navigationController(_ navigationController: UINavigationController,
didShow viewController: UIViewController,
animated: Bool) {
if (viewController == self.viewControllers.first) {
// Keep the gesture disabled if we're at the root to avoid back swipes
// from corrupting the navigation stack.
self.interactivePopGestureRecognizer?.isEnabled = false
} else {
self.interactivePopGestureRecognizer?.isEnabled = true
}
debugPrint("------(#function) (viewController) " +
"enabled: (self.interactivePopGestureRecognizer?.isEnabled)" +
"------")
}
}