今天写项目的时候遇到一个需求就是NavigationBar上面要求写两个自定义的navigationItem,并且是要求图片在上文字在下。这其实以前也写过但是现在很生疏,于是我做完之后就总结了一下几种情况,无非就是:图片在上文字在下、图片在下文字在上(基本用不到)、图片在左文字在右、图片在右文字在左。
首先呢,我的需求是在NavigationBar上做事情,所以先写一个UIBarButtonItem+Category 类别:
#import
@interface UIBarButtonItem (Category)
typedef void(^BarButtonItemBlock) ();
/**
* 用图片创建barButtonItem
*/
+ (instancetype)barButtonItemWithImage:(NSString *)image andBarButtonItemBlock:(BarButtonItemBlock)barButtonItemBlock;
/**
* 纯文字创建barButtonItem 白色文字
*/
+ (instancetype)barButtonItemWithTitle:(NSString *)title andBarButtonItemBlock:(BarButtonItemBlock)barButtonItemBlock;
/**
* 纯文字创建barButtonItem 自定义文字
*/
+(instancetype)barButtonItemWithTitle:(NSString *)title titleColor:(UIColor *)titleColor andBarButtonItemBlock:(BarButtonItemBlock)barButtonItemBlock;
/*
用图片和文字组合创建barButtonItem
*/
+(instancetype)barButtonItemWithImage_up:(NSString *)imageName andBarButtonItemTitle:(NSString *)title barButtonItemBlock:(BarButtonItemBlock)block;
@end
#import "UIBarButtonItem+Category.h"
#import
@interface UIBarButtonItem ()
@property (nonatomic) BarButtonItemBlock barButtonItemBlock;
@end
@implementation UIBarButtonItem (Category)
+(instancetype)barButtonItemWithImage:(NSString *)image andBarButtonItemBlock:(BarButtonItemBlock)barButtonItemBlock
{
UIButton *btn = [UIButton buttonWithImageName:image];
UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithCustomView:btn];
item.barButtonItemBlock = barButtonItemBlock;
[btn addTarget:item action:@selector(clickItem) forControlEvents:UIControlEventTouchUpInside];
return item;
}
+(instancetype)barButtonItemWithTitle:(NSString *)title andBarButtonItemBlock:(BarButtonItemBlock)barButtonItemBlock
{
//默认是白色文字
return [self barButtonItemWithTitle:title titleColor:[UIColor whiteColor] andBarButtonItemBlock:barButtonItemBlock];
}
+(instancetype)barButtonItemWithTitle:(NSString *)title titleColor:(UIColor *)titleColor andBarButtonItemBlock:(BarButtonItemBlock)barButtonItemBlock
{
UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithTitle:title style:UIBarButtonItemStylePlain target:nil action:nil];
[item setTarget:item];
[item setAction:@selector(clickItem)];
item.barButtonItemBlock = barButtonItemBlock;
item.tintColor = titleColor;
return item;
}
+(instancetype)barButtonItemWithImage_up:(NSString *)imageName andBarButtonItemTitle:(NSString *)title barButtonItemBlock:(BarButtonItemBlock)block{
UIButton *btn = [UIButton buttonWithImageName:imageName andTitle:title];
UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithCustomView:btn];
item.barButtonItemBlock = block;
[btn addTarget:item action:@selector(clickItem) forControlEvents:UIControlEventTouchUpInside];
return item;
}
- (void)clickItem
{
if (self.barButtonItemBlock) {
self.barButtonItemBlock();
}
}
static void *key = &key;
-(void)setBarButtonItemBlock:(BarButtonItemBlock)barButtonItemBlock
{
objc_setAssociatedObject(self, & key, barButtonItemBlock, OBJC_ASSOCIATION_COPY);
}
-(BarButtonItemBlock)barButtonItemBlock
{
return objc_getAssociatedObject(self, &key);
}
@end
这个类别里就会用到UIButton的类别方法了:
UIButton+Awesome.h
#import
@interface UIButton (Awesome)
/*
图片在文字上面
*/
+ (instancetype) buttonWithImageName:(NSString *)imageName andTitle:(NSString *)title;
@end
#import "UIButton+Awesome.m"
+ (instancetype) buttonWithImageName:(NSString *)imageName andTitle:(NSString *)title{
float spacing = 3;//图片和文字的上下间距
UIImage *image = [UIImage imageNamed:imageName];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame = CGRectMake(0, 0, image.size.width,20);
[btn setImage:image forState:UIControlStateNormal];
[btn setImage:image forState:UIControlStateHighlighted];
[btn setTitle:title forState:UIControlStateNormal];
[btn setTitle:title forState:UIControlStateHighlighted];
btn.titleLabel.font = [UIFont systemFontOfSize:10];
// 1. 得到imageView和titleLabel的宽、高
CGFloat imageWith = btn.imageView.frame.size.width;
CGFloat imageHeight = btn.imageView.frame.size.height;
CGFloat labelWidth = 0.0;
CGFloat labelHeight = 0.0;
if ([UIDevice currentDevice].systemVersion.floatValue >= 8.0) {
// 由于iOS8中titleLabel的size为0,用下面的这种设置
labelWidth = btn.titleLabel.intrinsicContentSize.width;
labelHeight = btn.titleLabel.intrinsicContentSize.height;
} else {
labelWidth = btn.titleLabel.frame.size.width;
labelHeight = btn.titleLabel.frame.size.height;
}
// 2. 声明全局的imageEdgeInsets和labelEdgeInsets
UIEdgeInsets imageEdgeInsets = UIEdgeInsetsZero;
UIEdgeInsets labelEdgeInsets = UIEdgeInsetsZero;
imageEdgeInsets = UIEdgeInsetsMake(-labelHeight-spacing/2.0, 0, 0, -labelWidth);
labelEdgeInsets = UIEdgeInsetsMake(0, -imageWith, -imageHeight-spacing/2.0 -spacing, 0);
// 4. 赋值
btn.titleEdgeInsets = labelEdgeInsets;
btn.imageEdgeInsets = imageEdgeInsets;
// [btn setBackgroundImage:image forState:UIControlStateNormal];
// [btn setBackgroundImage:image forState:UIControlStateHighlighted];
return btn;
}
然后在我的控制器中这样写,加上你的图和文字就可以了:
self.navigationItem.leftBarButtonItem = [UIBarButtonItem barButtonItemWithImage_up:@"yuyue" andBarButtonItemTitle:@"预约" barButtonItemBlock:^{
}];
请看图:
接下来重点来了!!!做完项目之后,我总结了一下我开始说的那四种情况:
UIButton+ImageTitleSpacing.h
#import
#import
typedef NS_ENUM(NSUInteger, MKButtonEdgeInsetsStyle) {
MKButtonEdgeInsetsStyleTop, // image在上,label在下
MKButtonEdgeInsetsStyleLeft, // image在左,label在右
MKButtonEdgeInsetsStyleBottom, // image在下,label在上
MKButtonEdgeInsetsStyleRight // image在右,label在左
};
@interface UIButton (ImageTitleSpacing)
/**
* 设置button的titleLabel和imageView的布局样式,及间距
*
* @param style titleLabel和imageView的布局样式
* @param space titleLabel和imageView的间距
*/
- (void)layoutButtonWithEdgeInsetsStyle:(MKButtonEdgeInsetsStyle)style
imageTitleSpace:(CGFloat)space;
@end
UIButton+ImageTitleSpacing.m
@implementation UIButton (ImageTitleSpacing)
- (void)layoutButtonWithEdgeInsetsStyle:(MKButtonEdgeInsetsStyle)style
imageTitleSpace:(CGFloat)space
{
// 1. 得到imageView和titleLabel的宽、高
CGFloat imageWith = self.imageView.frame.size.width;
CGFloat imageHeight = self.imageView.frame.size.height;
CGFloat labelWidth = 0.0;
CGFloat labelHeight = 0.0;
if ([UIDevice currentDevice].systemVersion.floatValue >= 8.0) {
// 由于iOS8中titleLabel的size为0,用下面的这种设置
labelWidth = self.titleLabel.intrinsicContentSize.width;
labelHeight = self.titleLabel.intrinsicContentSize.height;
} else {
labelWidth = self.titleLabel.frame.size.width;
labelHeight = self.titleLabel.frame.size.height;
}
// 2. 声明全局的imageEdgeInsets和labelEdgeInsets
UIEdgeInsets imageEdgeInsets = UIEdgeInsetsZero;
UIEdgeInsets labelEdgeInsets = UIEdgeInsetsZero;
// 3. 根据style和space得到imageEdgeInsets和labelEdgeInsets的值
switch (style) {
case MKButtonEdgeInsetsStyleTop:
{
imageEdgeInsets = UIEdgeInsetsMake(-labelHeight-space/2.0, 0, 0, -labelWidth);
labelEdgeInsets = UIEdgeInsetsMake(0, -imageWith, -imageHeight-space/2.0 -space, 0);
}
break;
case MKButtonEdgeInsetsStyleLeft:
{
imageEdgeInsets = UIEdgeInsetsMake(0, -space/2.0, 0, space/2.0);
labelEdgeInsets = UIEdgeInsetsMake(0, space/2.0, 0, -space/2.0);
}
break;
case MKButtonEdgeInsetsStyleBottom:
{
imageEdgeInsets = UIEdgeInsetsMake(0, 0, -labelHeight-space/2.0, -labelWidth);
labelEdgeInsets = UIEdgeInsetsMake(-imageHeight-space/2.0, -imageWith, 0, 0);
}
break;
case MKButtonEdgeInsetsStyleRight:
{
imageEdgeInsets = UIEdgeInsetsMake(0, labelWidth+space/2.0, 0, -labelWidth-space/2.0);
labelEdgeInsets = UIEdgeInsetsMake(0, -imageWith-space/2.0, 0, imageWith+space/2.0);
}
break;
default:
break;
}
// 4. 赋值
self.titleEdgeInsets = labelEdgeInsets;
self.imageEdgeInsets = imageEdgeInsets;
}
@end
这样,按钮的文字和图片无论是哪种位置都可以用这个方法来解决了。
最后,兄弟如果对你有帮助,就顶一下吧。如果你觉得有什么不足之处也可以评论,一起讨论。