iOS开发:关于UINavigationItem和tintColor的沉思

Posted wuwuFQ

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS开发:关于UINavigationItem和tintColor的沉思相关的知识,希望对你有一定的参考价值。

ios开发:关于UINavigationItem和tintColor的沉思

在导航使用过程中,我们经常会自定义导航上面的按钮,接下来我要谈的需求是:自定义 导航左侧返回按钮和右侧两个按钮

  • 导航按钮可自定义大小(因为两个系统的按钮离的太远)
  • 导航按钮支持tintColor(就是和电池栏保持一个色调)
  • 导航按钮支持原图(也是就不受tintColor影响)

接下来我们围绕三个需求点,展开聊一聊。

三个按钮都是一样的思想和逻辑,我们用一个来举例子🌰。

导航按钮可自定义大小

  • 先初始化一个按钮,这里我指定了宽高和字体
- (UIButton *)actionItem_1 
    if (!_actionItem_1) 
        _actionItem_1 = [UIButton buttonWithType:UIButtonTypeSystem];
        _actionItem_1.frame = CGRectMake(0, 0, 32, 32);
        _actionItem_1.titleLabel.font = [UIFont systemFontOfSize:14];
        _actionItem_1.imageView.contentMode = UIViewContentModeScaleAspectFit;
        [_actionItem_1 addTarget:self action:@selector(didTapActionItem) forControlEvents:UIControlEventTouchUpInside];
    
    return _actionItem_1;

    UIView *containVew_1 = [[UIView alloc] initWithFrame:self.actionItem_1.bounds];
    [containVew_1 addSubview:self.actionItem_1];
    self.navigationItem.rightBarButtonItem = self.actionItem_1;

一个冷知识:::导航按钮自定义,用UIButton就可以,但是如果加载网络图片会有变形的问题,而且UIButton的frame也不会是32,用containVew接收一下,布局就没有问题了

设置文本

如果文字特别多,三四个字,那我设置32的宽度就有问题了。

//计算文本宽度

+ (CGFloat)calculateWidthOf:(NSString *)string font:(UIFont*)font 
    NSDictionary *dic = @NSFontAttributeName:font;
    CGRect rect = [string boundingRectWithSize:CGSizeMake(0, 50) options:NSStringDrawingUsesLineFragmentOrigin |
                   NSStringDrawingUsesFontLeading attributes:dic context:nil];
    return rect.size.width;


使用以上代码计算出文本宽度,重设 self.actionItem_1的宽度即可。

设置图片

本地的图片可以直接设置,网络图片可以使用SDWebImage等策略。
我加载的网络图片,后面会介绍到,接着看。

[[SDWebImageManager sharedManager] loadImageWithURL:url options:SDWebImageRetryFailed progress:^(NSInteger receivedSize, NSInteger expectedSize, NSURL * _Nullable targetURL) 
            
         completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) 
            dispatch_async(dispatch_get_main_queue(), ^(void)
                if (image) 
                   [self.actionItem_1 setImage:image forState:UIControlStateNormal];
                
            );
        ];

导航按钮支持tintColor

我们要先了解tintColor 是什么,知其然知其所以然。

  • //是个UIColor ,iOS5.0以上支持,通过superview层次继承而来
@property(null_resettable, nonatomic,strong)   UIColor     *tintColor API_AVAILABLE(ios(5.0)); // The tintColor is inherited through the superview hierarchy. See UIView for more information.
  • // 此属性对UIButtonTypeCustom类型的按钮没有效果。对于自定义按钮,必须自己实现与“tintColor”相关的任何行为。
  • 所以我自定义的按钮是UIButtonTypeSystem 类型的
Discussion
All subclasses of UIView derive their behavior for tintColor from the base class. See the discussion of tintColor at the UIView level for more information.
This property has no default effect for buttons with type UIButtonTypeCustom. For custom buttons, you must implement any behavior related to tintColor yourself.
  • 可以根据业务设置颜色
self.actionItem_1.tintColor = [UIColor blackColor];

导航按钮支持原图

有这么个需求逻辑:按钮我想统一着色,但是业务可以更换图片,这个图片不是非黑即白的,我想保持我的五彩斑斓不被tintColor所影响,既当···又立···,好,支持!

用到UIImageRenderingMode属性

typedef NS_ENUM(NSInteger, UIImageRenderingMode) 
    UIImageRenderingModeAutomatic,          // 使用默认渲染模式    
    UIImageRenderingModeAlwaysOriginal,     // 始终绘制原始图像,而不将其视为模板         
    UIImageRenderingModeAlwaysTemplate,     // 始终将图像绘制为模板图像,忽略其颜色信息
 API_AVAILABLE(ios(7.0));

//使用loadImageWithURL 当网络图片回来后,我们根据需求,来决策图片是否保持原始状态

[[SDWebImageManager sharedManager] loadImageWithURL:url options:SDWebImageRetryFailed progress:^(NSInteger receivedSize, NSInteger expectedSize, NSURL * _Nullable targetURL) 
            
         completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) 
            dispatch_async(dispatch_get_main_queue(), ^(void)
            if (image) 
            //isOriginal 你自己的业务判断条件
                if (isOriginal) 
                    image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
                 else 
                    image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
                
                [self.actionItem_1 setImage: image forState:UIControlStateNormal];
            
            );
        ];

以上是关于iOS开发:关于UINavigationItem和tintColor的沉思的主要内容,如果未能解决你的问题,请参考以下文章

使用良好的设计原则访问 UINavigationItem

在IOS中隐藏UINavigationItem

在 ios 中为 UINavigationitem(左栏按钮项)设置图像

iOS开发 : Navigation Bar的简单设置

我的 UINavigationitem 的 TitleView 在 ios 6 中得到扩展

iOS 11 - 使用大标题模式时的 UINavigationItem titleView