问题: 我想在像Whatsapp(< Chats(2)/< Chats(3))这样的弹出式视图控制器中自定义导航后退按钮标题。
但是,如果您使用
,则在弹出的视图控制器中分配新的backBarButtonItem将禁用滑动后退手势self.navigationController.interactivePopGestureRecognizer.delegate = self;
为了保持手势的正常运行,它会给你带来更多麻烦(太多bugssss)。
答案 0 :(得分:1)
您必须在显示标题的self.navigationItem.backBarButtonItem
之前设置ViewController
属性。
在Whatsapp示例中,您必须在聊天列表视图控制器上设置标题。
类似的东西:
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"chats(2)" style:UIBarButtonItemStylePlain target:nil action:nil];
之后,您只需设置title
的{{1}}。
答案 1 :(得分:1)
如果你想在整个应用程序中清空后退按钮标题,其中一个解决方案是在swizzled viewDidLoad中调用viewDidLoad并清空后退按钮标题。 并且它不会影响interactivePopGestureRecognizer的工作(确保启用interactivePopGestureRecognizer)。
@implementation UIViewController (Customizations)
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[UIViewController swizzleClass:[UIViewController class] method:@"viewDidLoad"];
});
}
+ (void)swizzleClass:(Class)class method:(NSString*)methodName {
SEL originalMethod = NSSelectorFromString(methodName);
SEL newMethod = NSSelectorFromString([NSString stringWithFormat:@"%@%@", @"override_", methodName]);
[self swizzle:class from:originalMethod to:newMethod];
}
+ (void)swizzle:(Class)class from:(SEL)original to:(SEL)new {
Method originalMethod = class_getInstanceMethod(class, original);
Method newMethod = class_getInstanceMethod(class, new);
if(class_addMethod(class, original, method_getImplementation(newMethod), method_getTypeEncoding(newMethod))) {
class_replaceMethod(class, new, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
} else {
method_exchangeImplementations(originalMethod, newMethod);
}
}
- (void)override_viewDidLoad {
//Empty back button title
UIBarButtonItem *backButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];
[self.navigationItem setBackBarButtonItem:backButtonItem];
[self override_viewDidLoad];
}
@end
答案 2 :(得分:0)
对于那些只想使用UINavigationController并修复此问题的人。我在Swift中为UINavigationController编写了一个扩展。
如果你很快刷回来,它就不会出现问题。
extension UINavigationController: UINavigationControllerDelegate, UIGestureRecognizerDelegate {
public override static func initialize() {
struct Static {
static var token: dispatch_once_t = 0
}
if self !== UINavigationController.self {
return
}
dispatch_once(&Static.token) {
// Swizzle viewDidLoad
self.swizzleViewDidLoad()
// Swizzle pushViewController
self.swizzlePushController()
}
}
// MARK: - Helpers
static func swizzleViewDidLoad() {
let originalViewDidLoadSelector = #selector(UINavigationController.viewDidLoad)
let swizzledViewDidLoadSelector = #selector(UINavigationController.newViewDidLoad)
let originalViewDidLoadMethod = class_getInstanceMethod(self, originalViewDidLoadSelector)
let swizzledViewDidLoadMethod = class_getInstanceMethod(self, swizzledViewDidLoadSelector)
let didAddViewDidLoadMethod = class_addMethod(self, originalViewDidLoadSelector, method_getImplementation(swizzledViewDidLoadMethod), method_getTypeEncoding(swizzledViewDidLoadMethod))
if didAddViewDidLoadMethod {
class_replaceMethod(self, swizzledViewDidLoadSelector, method_getImplementation(originalViewDidLoadMethod), method_getTypeEncoding(swizzledViewDidLoadMethod))
} else {
method_exchangeImplementations(originalViewDidLoadMethod, swizzledViewDidLoadMethod);
}
}
static func swizzlePushController() {
let originalPushControllerSelector = #selector(UINavigationController.pushViewController(_:animated:))
let swizzledPushControllerSelector = #selector(UINavigationController.newPushViewController(_:animated:))
let originalPushControllerMethod = class_getInstanceMethod(self, originalPushControllerSelector)
let swizzledPushControllerMethod = class_getInstanceMethod(self, swizzledPushControllerSelector)
let didAddPushControllerMethod = class_addMethod(self, originalPushControllerSelector, method_getImplementation(swizzledPushControllerMethod), method_getTypeEncoding(swizzledPushControllerMethod))
if didAddPushControllerMethod {
class_replaceMethod(self, swizzledPushControllerSelector, method_getImplementation(originalPushControllerMethod), method_getTypeEncoding(swizzledPushControllerMethod))
} else {
method_exchangeImplementations(originalPushControllerMethod, swizzledPushControllerMethod);
}
}
// MARK: - Method Swizzling
func newViewDidLoad() {
self.newViewDidLoad()
self.interactivePopGestureRecognizer?.delegate = self
self.delegate = self
}
func newPushViewController(viewController: UIViewController, animated: Bool) {
self.interactivePopGestureRecognizer?.enabled = false
self.newPushViewController(viewController, animated: animated)
}
// MARK: - UINavigationControllerDelegate
public func navigationController(navigationController: UINavigationController, didShowViewController viewController: UIViewController, animated: Bool) {
self.interactivePopGestureRecognizer?.enabled = true
}
}
答案 3 :(得分:-1)
答案:
花了一天时间来解决这个问题,我有一个非常简单易用的解决方案,适用于iOS 6& iOS 7:
1)。 AppDelegate中的自定义样式(颜色,字体)(假设您将对所有控制器使用相同的样式)
2)。像这样创建一个自定义UINavigationController:
CustomBackNavigationController.h
@interface CustomBackNavigationController : UINavigationController <UINavigationControllerDelegate>
@property (nonatomic, strong) UIBarButtonItem *backButton;
@end
CustomBackNavigationController.m
@implementation CustomBackNavigationController
@synthesize backButton;
- (void)viewDidLoad
{
[super viewDidLoad];
self.delegate = self;
}
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
backButton = [[UIBarButtonItem alloc] initWithTitle:@"Chats" style:UIBarButtonItemStyleBordered target:nil action:nil];
viewController.navigationItem.backBarButtonItem = backButton;
}
@end
在弹出的视图控制器中,只需像这样更改backButton标题
- (void)someMethod
{
CustomBackNavigationController *customBackNavigationController = (CustomBackNavigationController *) self.navigationController;
[customBackNavigationController.backButton setTitle:@"Chats (1)"];
}
那就是它!