iOS 自定义导航栏

 

 

iOS 系统中导航栏的转场解决方案与最佳实践 

https://www.infoq.cn/article/MC11aIM1hw4TzrwOb8rW/

 

ios5之自定义UINavigationBar 、

 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:以上就是我所知道的自定义按钮的方式,如果有不足或者说的不对的地方,希望大家多多指正,可以评论指出或者私信我。

demo地址

方法交换分类

UINavigationController分类

参考文章:

iOS关于设置一个自定义的导航控制器返回按钮

ios自定义图片替换系统导航栏返回按钮样式

iOS返回按钮自定义



作者:独孤红雨
链接: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);
title来源的优先级

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
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
 
其他backButtonDisplayMode相关:
https://www.jianshu.com/p/fcdbf9dbd38b
在 iOS14 通过 backButtonDisplayMode 来管理你的后退按钮 https://juejin.cn/post/6873414408408662029
 
 
 

去掉 iOS 导航栏返回按钮文本三种方案

转:https://www.sohu.com/a/471051832_115128

方案一

  1. 自定义 UINavigationController

  2. 遵守 UINavigationBarDel协议

  3. 实现下面方法:

# 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; 

方案二

  1. 自定义 UINavigationController

  2. 遵守 <UINavigationBarDelegate> 协议

  3. 实现下面方法:

# pragmamark --------- UINavigationBarDelegate 

- ( BOOL)navigationBar:( UINavigationBar*)navigationBar shouldPushItem:( UINavigationItem*)item { 

//设置导航栏返回按钮文字为透明的,可能造成导航标题不居中的问题

[[ UIBarButtonItemappearance] setTitleTextAttributes:@{ NSForegroundColorAttributeName: [ UIColorclearColor]} forState: UIControlStateNormal]; 

[[ UIBarButtonItemappearance] setTitleTextAttributes:@{ NSForegroundColorAttributeName: [ UIColorclearColor]} forState: UIControlStateHighlighted]; 

returnYES; 

方案三(推荐)

  1. 给 UIViewController 添加类别(这里的类别不需要导入可直接使用)

  2. 然后在 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;

在这里,如果不想让返回按钮显示任何文字,有两种方式:

  1. 如上述方法所示,只要设置barButtonItemtitle""即可;
  2. 也可以在本视图中通过[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;

backIndicatorImagebackIndicatorTransitionMaskImage是什么呢?看官方文档:

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

 

posted @ 2022-06-06 18:01  LiuZX_贤  阅读(1187)  评论(0编辑  收藏  举报