iOS 自定义导航栏
iOS 系统中导航栏的转场解决方案与最佳实践
https://www.infoq.cn/article/MC11aIM1hw4TzrwOb8rW/
https://blog.csdn.net/nextstudio/article/details/8634728
ios6自定义导航栏
http://www.cppblog.com/TianShiDeBaiGu/archive/2014/06/12/207262.html
自定义导航栏,设置全局导航条外观
https://blog.51cto.com/iosre/5261350
自定义UINavigationBar样式
https://www.jianshu.com/p/f7f48ccab1d8
如何自定义 UINavigationBar 的高度
https://www.jianshu.com/p/5abc591feeda
iOS 修改navigationController返回按钮颜色和文字
http://t.zoukankan.com/gaozhang12345-p-10818481.html
设置导航栏返回按钮的另一种方式 https://blog.csdn.net/shishaobo/article/details/52192094
自定义backbarbuttonitem 在开发过程中,我们很多时候需要用自定义的返回按钮,而不使用系统自带的返回按钮。我之前的经常做法是:将系统的返回按钮隐藏,定制leftnavigationitem,在iOS7之后,
系统添加了右划返回事件,但是隐藏掉返回按钮后,系统的这个手势事件会消失,我们的做法是自己开启手势识别。有关开启手势识别功能的说明,在此不多描述,请自行Google。
在navigationcontroller的第一个controller中进行手势以及当前控制器的判断。
我现在的做法是学习apple提供的官方examplecode,使用下面的代码: UIImage *backButtonBackgroundImage = [UIImage imageNamed:@"Menu"]; // The background should be pinned to the left and not stretch. backButtonBackgroundImage = [backButtonBackgroundImage resizableImageWithCapInsets:UIEdgeInsetsMake(0, backButtonBackgroundImage.size.width - 1, 0, 0)]; id appearance = [UIBarButtonItem appearanceWhenContainedIn:[CustomBackButtonNavController class], nil]; [appearance setBackButtonBackgroundImage:backButtonBackgroundImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; UIBarButtonItem *backBarButton = [[UIBarButtonItem alloc] initWithTitle:@" " style:UIBarButtonItemStylePlain target:nil action:NULL]; self.navigationItem.backBarButtonItem = backBarButton;
有些朋友可能不大熟悉:appearanceWhenContainedIn这个方法,这个方法的的定义是这样的: + (instancetype)appearanceWhenContainedIn:(nullable Class <UIAppearanceContainer>)ContainerClass, ... NS_REQUIRES_NIL_TERMINATION NS_DEPRECATED_IOS(5_0, 9_0, "Use +appearanceWhenContainedInInstancesOfClasses: instead") __TVOS_PROHIBITED;
iOS 11 使用两种方法替换(Method Swizzling)去掉导航栏返回按钮的文字
https://www.jb51.net/article/139613.htm
使用运行时机制,将后退按钮文字清空
https://www.cnblogs.com/anywherego/p/5570283.html
使用backIndicatorImage导航栏系统返回键箭头偏移 https://www.jianshu.com/p/091479643bff
自定义导航栏返回键有多重方式,系统返回键、左键、或者自定义导航栏等等;
下面介绍的是系统返回键自定义图片、文字样式
1、替换返回键图片 UIImage*back = [[UIImage imageNamed:YLNavBackIconName] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; [UINavigationBar appearance].backIndicatorTransitionMaskImage = back; [UINavigationBar appearance].backIndicatorImage = back;
2、文字替换 self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"返回" style:UIBarButtonItemStylePlain target:nil action:nil];
之前使用的好好地,产品不断迭代更新,返回键样式一直改,某一天突然发现返回箭头不居中,向上偏移了。
然后尝试各种方法让其与文字居中,方法如下:
研究发现系统返回键尺寸:13*21 ,发现超过这个尺寸才会偏移,图片尺寸1倍图调整比这个高度小,完美显示。
方案一:
自定义导航栏。
方案二: UIImage*back = [[UIImage imageNamed:YLNavBackIconName] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; //隐藏系统的 [UINavigationBar appearance].backIndicatorTransitionMaskImage = [UIImage new]; [UINavigationBar appearance].backIndicatorImage = [UIImage new]; //设置新的 [[UIBarButtonItem appearance] setBackButtonBackgroundImage:[back resizableImageWithCapInsets:UIEdgeInsetsMake(0, back.size.width, 0, 0)] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; 解决。
方案三: 不需要返回文字,能解决箭头居中 if (@available(iOS 11.0, *)) { //箭头偏移 [[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(0, -10) forBarMetrics:UIBarMetricsDefault]; }
其他:
iOS 13导航栏外观setBackIndicatorImage不工作
https://cloud.tencent.com/developer/ask/sof/546276
ios – 设置backIndicatorImage之后,如何重用系统的后退图标?
https://www.nuomiphp.com/eplan/636572.html
设置导航栏的返回按钮只保留箭头 https://www.jianshu.com/p/b15568c460b4
iOS 11 之前,如果使用系统自带的返回按钮,为了达到导航栏返回按钮只显示返回图片,不显示文字信息的效果,可以通过设置导航栏的的属性
[[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(0, -60)forBarMetrics:UIBarMetricsDefault];
而在iOS 11版本开始,上边的方法就不好用了;之前开发时更多的是用自定义返回按钮去实现效果.今天逛csdn时,发现了一种思路,链接https://blog.csdn.net/wang_gwei/article/details/78975305 ,需要写的代码不多也不影响系统自带的侧滑返回手势功能使用,故作笔记:
第一步:
默认状态下返回按钮文字设置为透明
// 修改导航按钮颜色
// [[UINavigationBar appearance] setTintColor:[UIColor whiteColor]];
// 隐藏返回按钮的文字,只保留箭头
[[UIBarButtonItem appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor clearColor]}forState:UIControlStateNormal];//将title 文字的颜色改为透明
第二步:
高亮状态下返回按钮文字也需要设置为透明,否则点击按时时候会出现文字,就比较奇怪了
[[UIBarButtonItem appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor clearColor]}forState:UIControlStateHighlighted]; //将title 文字的颜色改为透明
iOS 11,关于隐藏导航栏左侧返回按钮的标题title
https://blog.csdn.net/Wheat_yh/article/details/78083384
iOS 11导航栏返回按钮隐藏标题
https://www.jianshu.com/p/766bd01b5b6b
IOS15全局设置返回按钮
https://www.jianshu.com/p/09d1544c0330
iOS关于自定义返回按钮
转:https://www.jianshu.com/p/3dfc0ba78bb2?utm_campaign=maleskine
前言:
就在上个月也就是年末的时候,打开了以前的一个项目,忽然发现导航栏返回按钮几乎看不到了,一直忙另外一个项目,直到这几天才处理一下,总结一下遇到的一些问题和处理方法。
问题截图如下:
原来没有任何问题,但是iOS11更新之后就这样了,运行下之后发现,下面打印了一堆,仔细一看好像是说约束重复的问题,网上搜索下,目前没找到原因(可能是iOS11系统在导航栏里面的布局和控件都变化了)。下面说一些自定义返回按钮的一些方法总结,以及最后如何解决这个问题。
代码如下:
UIImage *backButtonImage = [[UIImage imageNamed:@”箭头left40x40.png”] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 40, 0, 0) resizingMode:UIImageResizingModeTile];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:backButtonImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(NSIntegerMin, NSIntegerMin) forBarMetrics:UIBarMetricsDefault];
自定义返回按钮的一些方法:
1、在父视图中修改
UIBarButtonItem *backItem = [[UIBarButtonItem alloc] initWithTitle:@”返回上级界面” style:UIBarButtonItemStylePlain target:nil action:nil]; self.navigationItem.backBarButtonItem = backItem;
●这种方法只是修改文字部分,如果文字设置问空,但是箭头右边空白部分依然可以响应返回方法。
UIBarButtonItem *backItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@”箭头left40x40″] style:UIBarButtonItemStylePlain target:nil action:nil]; self.navigationItem.backBarButtonItem = backItem;
●这种方法只是改变返回按钮的文字部分,文字被替换成我们设置的图片,左边原本的箭头依然存在。
UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
backButton.frame = CGRectMake(0, 0, 30, 30);
[backButton setTitle:@”返回” forState:UIControlStateNormal];
[backButton setImage:[[UIImage imageNamed:@”箭头left40x40″] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] forState:UIControlStateNormal];
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
●这种方法会使返回按钮文字部分消失,图片也不起效果。
UIBarButtonItem *backItem = [[UIBarButtonItem alloc] initWithTitle:@”返回” style:UIBarButtonItemStylePlain target:nil action:nil]; self.navigationController.navigationBar.backIndicatorImage = [[UIImage imageNamed:@”箭头left40x40″] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
self.navigationController.navigationBar.backIndicatorTransitionMaskImage = [[UIImage imageNamed:@”箭头left40x40″] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
self.navigationItem.backBarButtonItem = backItem;
●这种方法会使返回按钮部分文字消失,图片需要渲染成原始的才有效果,而且图片会应用于本导航控制器下的所有有返回按钮的页面。
2、在本视图中修改
修改成只有图片的:
UIBarButtonItem *backItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@”箭头left40x40″] style:UIBarButtonItemStylePlain
target:self action:@selector(back)];
self.navigationItem.leftBarButtonItem = backItem;
修改成只有文字的:
UIBarButtonItem *backItem = [[UIBarButtonItem alloc] initWithTitle:@”返回” style:UIBarButtonItemStylePlain target:self action:@selector(back)]; self.navigationItem.leftBarButtonItem = backItem;
自定义文字和图片的:
UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
backButton.frame = CGRectMake(0, 0, 30, 30);
[backButton setTitle:@”返回” forState:UIControlStateNormal];
[backButton setImage:[[UIImage imageNamed:@”箭头left40x40″] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] forState:UIControlStateNormal];
[backButton addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside];
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
注意:上面这3种方法都会使返回按钮偏右,不大美观;而且会使系统自带的右滑手势返回移除控制的功能失效,解决办法就是在后面添加一句代码,让导航控制器重新设置这个功能,解决代码如下:
self.navigationController.interactivePopGestureRecognizer.delegate = nil;
以上这些方法都是只是在一个视图中生效,但是大多数项目自定义返回按钮的需求都是全局一样的,所以下面说一下全局设置的方法:
3、全局设置返回按钮
网上找到大多是说自定义一个导航控制器,重写其push方法,通过拦截push方法来进行设置,我对其稍微改动了点,代码如下:
-(void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated { if (self.childViewControllers.count > 0) { UIBarButtonItem *backItem = [[UIBarButtonItem alloc] initWithImage:[[UIImage imageNamed:@"箭头left40x40"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] style:UIBarButtonItemStylePlain target:self action:@selector(back)];
backItem.imageInsets = UIEdgeInsetsMake(0, -10, 0, 0);
viewController.navigationItem.leftBarButtonItem = backItem; viewController.hidesBottomBarWhenPushed = YES; } [super pushViewController:viewController animated:animated]; self.interactivePopGestureRecognizer.delegate = nil; } - (void)back {
[self popViewControllerAnimated:YES];
}
●这样改动的好处就是会更美观一点,点击返回响应区域也比较大;如果是原来的自定义按钮来设置,让箭头向左偏移一点,这样的话整个返回按钮的响应区域就会很小,而且会使箭头有部分无法响应返回。
当然网上也有说明使用分类的方法进行处理,代码如下:
– (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPushItem:(UINavigationItem *)item{
UIBarButtonItem *back = [[UIBarButtonItem alloc] initWithTitle:@”” style:UIBarButtonItemStylePlain target:nil action:nil];
item.backBarButtonItem = back;
return YES;
}
●这种方法也是有缺陷的,这样会使第一个控制器也出现返回按钮。
下面给出的最后一种方法,也就是我最后所使用的解决方法,代码如下:
#import “UINavigationController+Addtion.h”
#import “NSObject+Swizzling.h”
@implementation UINavigationController (Addtion)
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[self methodSwizzlingWithOriginalSelector:@selector(pushViewController:animated:) bySwizzledSelector:@selector(replacePushViewController:animated:)];
});
}
– (void)replacePushViewController:(UIViewController *)viewController animated:(BOOL)animated {
if (self.viewControllers.count > 0) {
UIBarButtonItem *backItem = [[UIBarButtonItem alloc] initWithImage:[[UIImage imageNamed:@”箭头left40x40″] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] style:UIBarButtonItemStylePlain target:self action:@selector(back)]; backItem.imageInsets = UIEdgeInsetsMake(0, -10, 0, 0);
viewController.navigationItem.leftBarButtonItem = backItem;
viewController.hidesBottomBarWhenPushed = YES;
}
[self replacePushViewController:viewController animated:animated];
self.interactivePopGestureRecognizer.delegate = nil;
}
– (void)back {
[self popViewControllerAnimated:YES];
}
@end
●这是添加一个NavicationController的分类,使用runtime进行方法交换,然后再执行原来的方法,并且右滑手势返回也可以使用。至于方法交换的代码下面给出:
Class class = [self class]; //原有方法
Method originalMethod = class_getInstanceMethod(class, originalSelector); //替换原有方法的新方法
Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
BOOL didAddMethod = class_addMethod(class,originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
if (didAddMethod) {
class_replaceMethod(class,swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
} else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
总结:
这些自定义返回按钮的方式,各有利弊,实际根据自己的项目需求使用,总有比较适合自己的方式。
PS:以上就是我所知道的自定义按钮的方式,如果有不足或者说的不对的地方,希望大家多多指正,可以评论指出或者私信我。
参考文章:
作者:独孤红雨
链接:https://www.jianshu.com/p/3dfc0ba78bb2
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
iOS 导航栏-返回按钮-自定义
转: https://www.jianshu.com/p/fb1c5bcf48d3
在开发过程中,我们经常遇到使用系统导航栏的功能,如何更改返回按钮的样式呢?
一、更改返回按钮图片
// 更换返回按钮的图片 UIImage *backButtonImage = [[UIImage imageNamed:@"bt_navigationBar_back"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; [UINavigationBar appearance].backIndicatorTransitionMaskImage = backButtonImage; [UINavigationBar appearance].backIndicatorImage = backButtonImage; // 返回按钮的文字置空(在UINavigationController的子类或者分类categary)中添加该方法 - (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPushItem:(UINavigationItem *)item { UIBarButtonItem *back = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil]; item.backBarButtonItem = back; return YES; }
二、重写返回按钮
重写返回按钮一般是添加leftBarButtonItems。如果导航栏添加了leftBarButtonItems之后,会自动隐藏返回按钮backBarButtonItem。
// 返回按钮 UIBarButtonItem *backBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[[UIImage imageNamed:@"bt_navigationBar_back"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] style:UIBarButtonItemStylePlain target:self action:@selector(backAction)]; self.navigationItem.leftBarButtonItem = backBarButtonItem; // 返回按钮的回调方法 - (void)backAction { }
三、拦截系统导航栏的返回按钮监听事件
当我们使用了系统的导航栏时,默认点击返回按钮是 pop 回上一个界面。但是在有时候,我们需要在点击导航栏的返回按钮时不一定要 pop 回上一界面,可能是其他的页面,我们需要拦截返回按钮的pop操作。
1、重写返回按钮
具体操作查看上面“二、重写返回按钮”。
缺点:若重写了某个界面的返回按钮,感觉应用整体就不统一了。而且每有一个界面有这个需求都需要重新自定义一个返回按钮,显得不优雅,工作繁琐。
2、为 UINavigationController 添加 category
//item将要push的时候调用,返回NO,则不能push - (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPushItem:(UINavigationItem *)item; // called to push. return NO not to. //item已经push后调用 - (void)navigationBar:(UINavigationBar *)navigationBar didPushItem:(UINavigationItem *)item; // called at end of animation of push or immediately if not animated //item将要pop时调用,返回NO,不能pop - (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item; // same as push methods //item已经pop后调用 - (void)navigationBar:(UINavigationBar *)navigationBar didPopItem:(UINavigationItem *)item;
我们可以为 UINavigatonController 创建一个 Category,来定制navigationBar: shouldPopItem: 的逻辑。
// UIViewController+BackButtonHandler.h @protocol BackButtonHandlerProtocol <NSObject> @optional // 重写下面的方法以拦截导航栏返回按钮点击事件,返回 YES 则 pop,NO 则不 pop -(BOOL)navigationShouldPopOnBackButton; @end @interface UIViewController (BackButtonHandler) <BackButtonHandlerProtocol> @end
// UIViewController+BackButtonHandler.m @implementation UIViewController (BackButtonHandler) @end @implementation UINavigationController (ShouldPopOnBackButton) - (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item { if([self.viewControllers count] < [navigationBar.items count]) { return YES; } BOOL shouldPop = YES; UIViewController* vc = [self topViewController]; if([vc respondsToSelector:@selector(navigationShouldPopOnBackButton)]) { shouldPop = [vc navigationShouldPopOnBackButton]; } if(shouldPop) { dispatch_async(dispatch_get_main_queue(), ^{ [self popViewControllerAnimated:YES]; }); } else { // 取消 pop 后,复原返回按钮的状态 for(UIView *subview in [navigationBar subviews]) { if(0. < subview.alpha && subview.alpha < 1.) { [UIView animateWithDuration:.25 animations:^{ subview.alpha = 1.; }]; } } } return NO; }
使用时,只需要在需要拦截返回按钮事件的控制器中,应用#import “UIViewController+BackButtonHandler.h”,并重写-(BOOL)navigationShouldPopOnBackButton方法即可。
- (BOOL)navigationShouldPopOnBackButton{ //拦截返回按钮后做的处理 //返回NO(一定要返回NO) return NO; }
链接:https://www.jianshu.com/p/fb1c5bcf48d3
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
iOS14 长按返回按钮 backButtonDisplayMode
转:https://www.jianshu.com/p/912dc6ba3d65
iOS 14中长按返回按钮会显示多级菜单,滑动后可以返回对应的页面。
在App上长按后title为空
backButtonDisplayMode
iOS 14新增了一个属性backButtonDisplayMode来定义title的来源
typedef NS_ENUM(NSInteger, UINavigationItemBackButtonDisplayMode) { /// Default mode, uses an appropriate title, followed by a generic title (typically 'Back'), then no title. UINavigationItemBackButtonDisplayModeDefault = 0, /// Generic titles only. Ignores .title and .backButtonTitle (but *not* .backBarButtonItem.title). UINavigationItemBackButtonDisplayModeGeneric = 1, /// Don't use a title, just the back button indicator image. UINavigationItemBackButtonDisplayModeMinimal = 2, } NS_SWIFT_NAME(UINavigationItem.BackButtonDisplayMode);
1.navigationItem.backBarButtonItem
2.navigationItem.backButtonTitle
3.navigationItem.title和viewController的title,同时设置显示为viewController的title
App中使用
UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil]; self.navigationItem.backBarButtonItem = item;
来隐藏返回按钮的标题,引起了上面的问题。
UINavigationItemBackButtonDisplayModeMinimal
Minimal模式下,返回按钮不显示title,但是 navigation stack可以显示出 title,未设置title的时候显示返回。
适配
if (@available(iOS 14.0, *)) { self.navigationItem.backButtonDisplayMode = UINavigationItemBackButtonDisplayModeMinimal; } else { UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil]; self.navigationItem.backBarButtonItem = item; }
作者:离离乱惑
链接:https://www.jianshu.com/p/912dc6ba3d65
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
去掉 iOS 导航栏返回按钮文本三种方案
方案一
-
自定义 UINavigationController
-
遵守 UINavigationBarDel协议
-
实现下面方法:
# pragmamark ——— UINavigationBarDelegate
– ( BOOL)navigationBar:( UINavigationBar*)navigationBar shouldPushItem:( UINavigationItem*)item {
//设置导航栏返回按钮文字
UIBarButtonItem*back = [[ UIBarButtonItemalloc] initWithTitle: nilstyle: UIBarButtonItemStylePlaintarget: nilaction: nil];
/*
NSMutableDictionary *textAttrs = [NSMutableDictionary dictionary];
textAttrs[UITextAttributeTextColor] = [UIColor whiteColor];
[back setTitleTextAttributes:textAttrs forState:UIControlStateNormal];
*/
item.backBarButtonItem = back;
returnYES;
}
❝
注意:该方法会出现部分子控制器页面的返回按钮文字出现的bug,需要在其子控制器页面的父控制器里再次如上设置返回按钮才行
子控制器页面的父控制器
# pragmamark ——– 生命周期函数
– ( void)viewDidLoad {
[ superviewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [ UIColorwhiteColor];
//重新设置下级子页面导航栏返回按钮文字
UIBarButtonItem*item = [[ UIBarButtonItemalloc] initWithTitle: nilstyle: UIBarButtonItemStylePlaintarget: nilaction: nil];
self.navigationItem.backBarButtonItem = item;
}
方案二
-
自定义 UINavigationController
-
遵守 <UINavigationBarDelegate> 协议
-
实现下面方法:
# pragmamark ——— UINavigationBarDelegate
– ( BOOL)navigationBar:( UINavigationBar*)navigationBar shouldPushItem:( UINavigationItem*)item {
//设置导航栏返回按钮文字为透明的,可能造成导航标题不居中的问题
[[ UIBarButtonItemappearance] setTitleTextAttributes:@{ NSForegroundColorAttributeName: [ UIColorclearColor]} forState: UIControlStateNormal];
[[ UIBarButtonItemappearance] setTitleTextAttributes:@{ NSForegroundColorAttributeName: [ UIColorclearColor]} forState: UIControlStateHighlighted];
returnYES;
}
方案三(推荐)
-
给 UIViewController 添加类别(这里的类别不需要导入可直接使用)
-
然后在 load 方法里面用 Method Swzilling 方法替换交换 ViewDidAppear 方法,代码如下:
#import “UIViewController+HideNavBackTitle.h”
#import <objc/runtime.h>
@implementationUIViewController( HideNavBackTitle)
+( void)load {
swizzleMethod([ selfclass], @selector(viewDidAppear:), @selector(ac_viewDidAppear));
}
//设置导航栏返回按钮文字
– ( void)ac_viewDidAppear{
self.navigationItem.backBarButtonItem = [[ UIBarButtonItemalloc]
initWithTitle: @””
style: UIBarButtonItemStylePlain
target: self
action: nil];
[ selfac_viewDidAppear];
}
voidswizzleMethod(Class class, SEL originalSelector, SEL swizzledSelector)
{
// the method might not exist in the class, but in its superclass
Method originalMethod = class_getInstanceMethod( class, originalSelector);
Method swizzledMethod = class_getInstanceMethod( class, swizzledSelector);
// class_addMethod will fail if original method already exists
BOOLdidAddMethod = class_addMethod( class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
// the method doesn’t exist and we just added one
if(didAddMethod) {
class_replaceMethod( class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
}
else{
method_exchangeImplementations(originalMethod, swizzledMethod);
}
}
@end
iOS 自定义导航栏返回按钮
转:https://blog.csdn.net/shuai265/article/details/79062998
原文地址
参考1:关于backBarButtonItem的N种方法
参考2:How to make custom UINavigationController back button image without title
需求
项目中经常需要自定义导航栏返回按钮,只显示文字或者图片
分析
自定义导航栏返回按钮的思路很多:
每个子视图控制器中修改 leftBarButtonItem 的样式,缺点是重复工作量大,如有变更不易修改。
基类中通过实现 UINavigationController 的代理判断是否是栈底,如果不是栈底,则修改 leftBarButtonItem 的样式。
在基类中设置backBarButtonItem,易于修改,工作量小。
Method Swizzling:将系统自带的backBarButtonItem方法替换成我们自定义的方法。
实现
方法2:
– (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
UIViewController *root = navigationController.viewControllers[0];
if (root != viewController) {
UIBarButtonItem *itemleft = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@”backBtn”] style:UIBarButtonItemStylePlain target:self action:@selector(popAction:)];
viewController.navigationItem.leftBarButtonItem = itemleft;
}
}
– (void)popAction:(UIBarButtonItem *)barButtonItem
{
[self.navigationController popViewControllerAnimated:YES];
}
方法3:
//只显示文字
//self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@”返回” style:UIBarButtonItemStylePlain target:nil action:nil];
//只显示图片
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[[UIImage imageNamed:@”nav_back”]
imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] style:UIBarButtonItemStylePlain target:nil action:nil];
//更改返回按钮填充颜色
//self.navigationController.navigationBar.tintColor = [UIColor darkGrayColor];
//隐藏默认的返回箭头
self.navigationController.navigationBar.backIndicatorImage = [UIImage new];
self.navigationController.navigationBar.backIndicatorTransitionMaskImage = [UIImage new];
方法4:
+(void)load{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Method originalMethodImp = class_getInstanceMethod(self, @selector(backBarButtonItem));
Method destMethodImp = class_getInstanceMethod(self, @selector(myCustomBackButton));
method_exchangeImplementations(originalMethodImp, destMethodImp);
});
}
static char kCustomBackButtonKey;
-(UIBarButtonItem *)myCustomBackButton{
UIBarButtonItem *item = [self myCustomBackButton];
if (item) {
return item;
}
item = objc_getAssociatedObject(self, &kCustomBackButtonKey);
if (!item) {
item = [[UIBarButtonItem alloc] initWithTitle:@”返回” style:UIBarButtonItemStylePlain target:nil action:NULL];
objc_setAssociatedObject(self, &kCustomBackButtonKey, item, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
return item;
}
– (void)dealloc
{
objc_removeAssociatedObjects(self);
}
————————————————
版权声明:本文为CSDN博主「shuai265」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/shuai265/article/details/79062998
iOS 15 返回按钮自定义图片失败问题修复方法
转:https://www.jianshu.com/p/f0427c92c67c
iOS 15系统 backIndicatorImage图片设置失败问题修复方法
在iOS15之前,我们是这样设置的
UINavigationBar *navigationBarAppearance = [UINavigationBar appearance]; navigationBarAppearance.backIndicatorImage = [UIImage imageNamed:@"image_common_navBackBlack"]; navigationBarAppearance.backIndicatorTransitionMaskImage = [UIImage imageNamed:@"image_common_navBackBlack"];
但是系统升级到iOS15之后,发现返回按钮不是自定义的图片了,设置失效,我们需要调整代码如下
if (@available(iOS 15.0, *)) { UINavigationBarAppearance *appearance = [[UINavigationBarAppearance alloc] init]; [appearance setBackIndicatorImage:[UIImage imageNamed:@"image_common_navBackBlack"] transitionMaskImage:[UIImage imageNamed:@"image_common_navBackBlack"]]; [[UINavigationBar appearance].scrollEdgeAppearance: appearance]; [[UINavigationBar appearance].standardAppearance:appearance]; }
通过set方法设置,就可以发现返回按钮的图片替换成功了
作者:fairy_happy
链接:https://www.jianshu.com/p/f0427c92c67c
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
iOS返回按钮自定义
转:https://www.jianshu.com/p/c229dc1aa325
引子
iOS导航栏返回按钮的自定义,无非就是自定义文字和自定义图像。
自定义文字
想要返回按钮显示不同的文字,只需在父视图进行这样修改:
//重新创建一个barButtonItem UIBarButtonItem *backItem = [[UIBarButtonItem alloc]initWithTitle:@"你想要设置的返回按钮文字" style:UIBarButtonItemStylePlain target:nil action:nil]; //设置backBarButtonItem即可 self.navigationItem.backBarButtonItem = backItem;
在这里,如果不想让返回按钮显示任何文字,有两种方式:
- 如上述方法所示,只要设置
barButtonItem
的title
为""
即可; - 也可以在本视图中通过
[UIBarButtonItem appearance]
对文字的范围进行设置,就像这样:
[[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(NSIntegerMin, NSIntegerMin)
forBarMetrics:UIBarMetricsDefault];
自定义返回图片
先说一下网上惯常的做法吧,就是在本视图中自定义一个UIButton
,然后设置UIButton
的图片,再给UIButton
添加事件进行返回上级视图的操作,代码类似于:
//创建一个UIButton UIButton *backButton = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 40, 40)]; //设置UIButton的图像 [backButton setImage:[UIImage imageNamed:@"left_select_img.png"] forState:UIControlStateNormal]; //给UIButton绑定一个方法,在这个方法中进行popViewControllerAnimated [backButton addTarget:self action:@selector(backItemClick) forControlEvents:UIControlEventTouchUpInside]; //然后通过系统给的自定义BarButtonItem的方法创建BarButtonItem UIBarButtonItem *backItem = [[UIBarButtonItem alloc]initWithCustomView:backButton]; //覆盖返回按键 self.navigationItem.leftBarButtonItem = backItem;
这种方式也可以达到目的,不过通过这种方式自定义返回按钮之后,系统的右滑返回的手势就会无法识别,通常的解决办法是再添加一个全局的手势操作。而且,这个方法自定义完之后的返回按钮一般都会偏右,然后再调位置。个人感觉有点麻烦,后来发现网上还有另外两种简便可行的方法。
1. 在本视图中修改
代码如下:
//方法1:在本视图中设置 UIImage *backButtonImage = [[UIImage imageNamed:@"left_select_img.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 40, 0, 0) resizingMode:UIImageResizingModeTile]; [[UIBarButtonItem appearance] setBackButtonBackgroundImage:backButtonImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; //参考自定义文字部分 [[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(NSIntegerMin, NSIntegerMin) forBarMetrics:UIBarMetricsDefault];
点进去这两个设置方法,会发现苹果官方给出了这么一段注释:
/* The remaining appearance modifiers apply solely to UINavigationBar back buttons and are ignored by other buttons. */ /* backgroundImage must be a resizable image for good results. */
大致意思也就是说:下边的方法主要是为了设置返回按钮,而且图片必须是拉伸过后的图片。这不正符合我们修改返回按钮的初衷吗?关于图片拉伸的各种效果,可以看这篇,写的非常清晰,有理有据。
2. 父视图中修改
代码如下:
//方法2:通过父视图NaviController来设置 UIBarButtonItem *backItem = [[UIBarButtonItem alloc]initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil]; self.navigationController.navigationBar.tintColor = [UIColor colorWithRed:0.99 green:0.50 blue:0.09 alpha:1.00]; //主要是以下两个图片设置 self.navigationController.navigationBar.backIndicatorImage = [UIImage imageNamed:@"left_select_img.png"]; self.navigationController.navigationBar.backIndicatorTransitionMaskImage = [UIImage imageNamed:@"left_select_img.png"]; self.navigationItem.backBarButtonItem = backItem;
backIndicatorImage
和backIndicatorTransitionMaskImage
是什么呢?看官方文档:
backIndicatorImage:The image shown beside the back button。
返回按钮底层的图片;
backIndicatorTransitionMaskImage:The image used as a mask for content during push and pop transitions.
视图转场过渡时被当作遮罩的图片(我也不懂什么意思)。
不过重要的是后边的Discussion
:
If you want to customize the back indicator image, you must also set backIndicatorTransitionMaskImage.
总结
这两种方式创建的自定义按钮,图片都在原来返回按钮的位置,而且右滑返回的手势依然可用!非常方便。
作者:dalianer
链接:https://www.jianshu.com/p/c229dc1aa325
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
动态更改 backBarButtonItem 的 title https://www.cnblogs.com/ihojin/p/change-backbarbuttonitem-text.html
iOS7 怎么修改去掉Navigation Bar上的返回按钮文本颜色,箭头颜色以及导航栏按钮的颜色 https://www.jianshu.com/p/d63bf98327c8
背景颜色 self.navigationController.navigationBar.barTintColor = [UIColor blackColor];\ //去掉导航条的半透明\ Navbar.translucent=YES;
按钮颜色(返回按钮的颜色设置) [[UINavigationBarappearance]setTintColor:[UIColorwhiteColor]]; 或者 self.navigationController.navigationBar.tintColor = [UIColor whiteColor];
标题字体和颜色: [self.navigationController.navigationBar setTitleTextAttributes:@{NSForegroundColorAttributeName : [UIColor whiteColor]}]; [[UIBarButtonItem appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor clearColor]} forState:UIControlStateNormal];
去掉返回按钮的字: self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:self.navigationItem.backBarButtonItem.style target:nil action:nil]; [[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(0, -60) forBarMetrics:UIBarMetricsDefault];
iOS13 tabbar黑线、背景色、 badgeColor适配
转:https://blog.csdn.net/qq_34848238/article/details/102658323
@implementation UITabBarItem (badgeColor) - (void)my_setBadgeValue:(NSString *)badgeValue { [self setBadgeValue:badgeValue]; UIColor *badgeColor = UIColorFromRGB(0x39E2C6); if (@available(iOS 10.0, *)) { [self setBadgeColor:badgeColor]; } else { // 这里替换角标颜色的图片,需要注意的时:这个图片size=(36px,36px),圆的 UIImage *badgeImage = [UIImage imageNamed:@"tabbarItem_blueBadge_icon"]; [self customBadgeColorWith:badgeImage]; } } - (void)customBadgeColorWith:(UIImage *)badgeImage { UIView *tabBarButton = (UIView *)[self performSelector:@selector(view)]; // iOS10以下的版本 角标其实是一张图片,所以我们一直找下去这个图片,然后替换他 for(UIView *subview in tabBarButton.subviews) { NSString *classString = NSStringFromClass([subview class]); if([classString rangeOfString:@"UIBadgeView"].location != NSNotFound) { for(UIView *badgeSubview in subview.subviews) { NSString *badgeSubviewClassString = NSStringFromClass([badgeSubview class]); if([badgeSubviewClassString rangeOfString:@"BadgeBackground"].location != NSNotFound) { [badgeSubview setValue:badgeImage forKey:@"image"]; } } } } } @end
以上代码是在iOS13之前设置的。
iOS13以后适配tabbar(去黑线),以下代码
if (@available(iOS 13.0, *)) { UITabBarAppearance *appearanceBar = [self.tabBar standardAppearance].copy; appearanceBar.backgroundImage = [UIImage instantiate1x1ImageWithColor:[UIColor whiteColor]]; appearanceBar.shadowImage = [UIImage instantiate1x1ImageWithColor:[UIColor clearColor]]; self.tabBar.standardAppearance = appearanceBar; NSMutableParagraphStyle *par = [[NSMutableParagraphStyle alloc]init]; par.alignment = NSTextAlignmentCenter; UITabBarItemStateAppearance *normal = appearanceBar.stackedLayoutAppearance.normal; if (normal) { normal.titleTextAttributes = @{NSForegroundColorAttributeName:UIColorFromRGB(0x333333),NSParagraphStyleAttributeName : par}; } UITabBarItemStateAppearance *selected = appearanceBar.stackedLayoutAppearance.selected; if (selected) { selected.titleTextAttributes = @{NSForegroundColorAttributeName:UIColorFromRGB(0x333333),NSParagraphStyleAttributeName : par}; } self.tabBar.standardAppearance = appearanceBar; }
这样我们就需要重新设置badgeColor,加上两句代码
appearanceBar.stackedLayoutAppearance.normal.badgeBackgroundColor = badgeColor;
appearanceBar.stackedLayoutAppearance.normal.badgeBackgroundColor = badgeColor;
————————————————
版权声明:本文为CSDN博主「大神路」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_34848238/article/details/102658323
转:https://www.jianshu.com/p/48ddc88299dd
iOS的UINavigationBar去掉黑线的几种方法分析 https://blog.csdn.net/jiege303/article/details/107507981
方案一:
写在AppDelegate里面
[[UINavigationBar appearance] setBackgroundImage:[[UIImage alloc] init] forBarPosition:UIBarPositionAny barMetrics:UIBarMetricsDefault];
[[UINavigationBar appearance] setShadowImage:[[UIImage alloc] init]];
方案二:
将UINavigationBar的clipsToBounds属性设成YES
原理:
Apple 翻译:对于自定义导航栏背景图片,自定义背景图片必须使用"setBackgroundImage: forBarMetrics: "这个方法.如果你不自定义背景图片的话,系统会替你设置一张背景图片. 意思就是,我们不设置背景图片,看到的其实是苹果已经给你设置了一张背景图片,有阴影,有黑线.(系统默认的,打开iPhone设置界面就是这样的).so,如果你想去掉黑线的话,就去掉苹果默认设置的图片吧! 写在AppDelegate里面 [[UINavigationBar appearance] setBackgroundImage:[[UIImage alloc] init] forBarPosition:UIBarPositionAny barMetrics:UIBarMetricsDefault]; [[UINavigationBar appearance] setShadowImage:[[UIImage alloc] init]]; 自己感受这段代码吧! 扩展: 相信大家有导航栏全透明的需求吧. 调用这段代码吧,图片可以任意设置,只要forBarMetrics那里是UIBarMetricsCompact就可以了. [self.navigationBar setBackgroundImage:[UIImage imageNamed:@"nav.jpg"] forBarMetrics:UIBarMetricsCompact]; 注意:调用这段代码想实现导航栏全透明必须先有 [[UINavigationBar appearance] setBackgroundImage:[[UIImage alloc] init] forBarPosition:UIBarPositionAny barMetrics:UIBarMetricsDefault]; [[UINavigationBar appearance] setShadowImage:[[UIImage alloc] init]]; 这段代码.(原因是,你先把苹果的默认导航栏背景图片去掉). ———————————————— 版权声明:本文为CSDN博主「搬砖小能手awesome」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/jiege303/article/details/107507981
其他参考:
去掉导航栏UINavigationBar最下面的黑线(三种方案) https://www.jianshu.com/p/202afecc7a9c
iOS 11 怎样为导航条上的 UIBarButtonItem 设置间距 https://zhuanlan.zhihu.com/p/32727565
其它关于导航栏的:
https://www.jianshu.com/p/c8ffb2bdda91
导航栏的返回按钮只保留那个箭头,去掉后边的文字,在网上查了一些资料,最简单且没有反作用的方法就是
[[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(0, -60)
forBarMetrics:UIBarMetricsDefault];
默认view将会被拉伸到全屏,
设置viewController的属性 edgesForExtendedLayout = UIRectEdgeNone; 导航里的view将不会被拉伸。
if ([self respondsToSelector:@selector(setEdgesForExtendedLayout:)]) {
self.edgesForExtendedLayout = UIRectEdgeNone;
}
其他属性设置可以参考:(英文)http://www.appcoda.com/customize-navigation-status-bar-ios-7/
(中文)http://beyondvincent.com/blog/2013/11/03/120-customize-navigation-status-bar-ios-7/
iOS系统中导航栏的转场解决方案与最佳实践
https://zhuanlan.zhihu.com/p/47734453
navigationBar透明
https://www.jianshu.com/p/bbbf6199de66
https://www.jianshu.com/p/2aba3be8328e
关于iOS导航栏返回按钮问题的解决方法
https://wenku.baidu.com/view/33f9b61940323968011ca300a6c30c225901f066.html?_wkts_=1667528307371
使用UISearchController时 navigationBar translucent 属性导致的问题总结
https://www.jianshu.com/p/5271c51e0b98
使用极致框架,导航栏自定义返回一行代码搞定
https://www.jianshu.com/p/59d88a53f340
ios navigation的返回按钮长按_Android Jetpack架构组件 — Navigation入坑详解 https://blog.csdn.net/weixin_42522167/article/details/113081247