iOS - UIButton图片文字各种位置的调整

今天写项目的时候遇到一个需求就是NavigationBar上面要求写两个自定义的navigationItem,并且是要求图片在上文字在下。这其实以前也写过但是现在很生疏,于是我做完之后就总结了一下几种情况,无非就是:图片在上文字在下、图片在下文字在上(基本用不到)、图片在左文字在右、图片在右文字在左。

首先呢,我的需求是在NavigationBar上做事情,所以先写一个UIBarButtonItem+Category 类别:

#import <UIKit/UIKit.h>

@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 <objc/runtime.h>

@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 <UIKit/UIKit.h>

@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 <UIKit/UIKit.h>
#import <objc/runtime.h>

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

这样,按钮的文字和图片无论是哪种位置都可以用这个方法来解决了。

最后,兄弟如果对你有帮助,就顶一下吧。如果你觉得有什么不足之处也可以评论,一起讨论。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值