我的应用程序遍布自定义后退按钮,看起来导航控制器不喜欢它。
所以,我希望iOS7的滑动到后退手势与我的自定义后退按钮一起工作。搜索并尝试了不同的方式,但似乎没有一个很有希望。我能得到的最接近的是http://keighl.com/post/ios7-interactive-pop-gesture-custom-back-button/。 但是,现在当我继续推送并弹出导航堆栈时,堆栈中的rootViewController会停止响应任何触摸。
有什么建议吗?
答案 0 :(得分:4)
像keighl建议的那样,对UINavigationController进行子类化是正确的方法。但他错过了对根视图控制器的检查,以避免在根视图上执行手势时冻结。 这是一个带有附加检查的修改版本:
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
答案 1 :(得分:1)
我遇到了同样的问题,这是我的解决方案:
在您的自定义NavigationController中,如MYNavigationController
,因为您将手势委托设置为navigationController,您可以在那里添加委托方法:
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{
if (self.viewControllers.count>1) {
return YES;
}
return NO;
}
答案 2 :(得分:0)
即使我遇到了同样的问题,我也通过修改您所指的链接中提供的代码来修复它。现在我的屏幕冻结很少,仍然找到永久修复。
@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{
//}
答案 3 :(得分:0)
以下是我对here
提出的类似问题的回答您可以使用一个小技巧来使本机手势正常工作。
创建UINavigationItem
的子类,然后覆盖leftBarButtonItems
方法:
- (NSArray*)leftBarButtonItems
{
return nil;
}
现在将此类用于具有自定义左UIBarButtonItem
的项目。手势有效!这是因为UINavigationController
认为没有剩下的项目并启用了手势。您仍然可以通过leftBarButtonItem
属性访问自定义项目。
答案 4 :(得分:0)
这是一个简单的UINavigationController
的Swift子类,你可以使用我改编自@ weak的答案。由于导航委托UIGestureRecognizerDelegate
处理启用和禁用弹出手势的工作,因此不需要实施navigationController(_:didShow:animated:)
。
在故事板或代码中使用此子类比在导航控制器中嵌入的其他控制器中进行一次性禁用更容易。
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)" +
"------")
}
}