Objective-C UIButton 自定義圖片位置

在項(xiàng)目中經(jīng)常會(huì)遇到一個(gè)按鈕上放一個(gè)圖片 位置有可能會(huì)是在標(biāo)題的上,下,左,右
如果一個(gè)按鈕,可以單獨(dú)設(shè)置titleEdgeInsets和imageEdgeInsets即可,但是如果有很多
類似的按鈕但是設(shè)置就很麻煩。為了解決這個(gè)問題 我們寫一個(gè)UIButton的Category

#import <UIKit/UIKit.h>

typedef NS_ENUM(NSUInteger,ButtonEdgeInsetsStyle) {
    ButtonEdgeInsetsStyleTop,
    ButtonEdgeInsetsStyleLeft,
    ButtonEdgeInsetsStyleRight,
    ButtonEdgeInsetsStyleBottom,
};

@interface UIButton (EdgeInsets)

/**非選中圖片*/
@property (copy, nonatomic) NSString *normalImageName;
/**選中圖片*/
@property (copy, nonatomic) NSString *selectedImageName;
/**默認(rèn)圖片*/
@property (copy, nonatomic) NSString *defaultImageName;

- (void)setImagePositionWithEdgeInsetsStyle:(ButtonEdgeInsetsStyle)style imageSpace:(CGFloat)space;

- (void)setDefaultImageWithNamed:(NSString *)imgName;

@end

為什么要設(shè)置三個(gè)圖片屬性,為了解決這樣的需求,比如有很多篩選按鈕,產(chǎn)品經(jīng)理說沒有排序用一張圖片,升序用一張圖片,降序用一張圖片。

#import "UIButton+EdgeInsets.h"
#import <objc/runtime.h>

@implementation UIButton (EdgeInsets)

- (void)setImagePositionWithEdgeInsetsStyle:(ButtonEdgeInsetsStyle)style imageSpace:(CGFloat)space
{
    
    // 得到imageView和titleLabel的寬、高
    CGFloat imageWith = self.currentImage.size.width;
    CGFloat imageHeight = self.currentImage.size.height;
    
    // 獲取TitleSize
    CGSize titleSize = [self sizeForText:[self titleForState:UIControlStateNormal] font:self.titleLabel.font size:CGSizeMake(HUGE, HUGE) mode:self.titleLabel.lineBreakMode];
    
    CGFloat labelWidth = titleSize.width;
    CGFloat labelHeight = titleSize.height;
   
    // 聲明全局的imageEdgeInsets和labelEdgeInsets
    UIEdgeInsets imageEdgeInsets = UIEdgeInsetsZero;
    UIEdgeInsets labelEdgeInsets = UIEdgeInsetsZero;
    
    // 根據(jù)style和space得到imageEdgeInsets和labelEdgeInsets的值
    switch (style) {
        case ButtonEdgeInsetsStyleTop: {
            imageEdgeInsets = UIEdgeInsetsMake(-labelHeight-space, 0, 0, -labelWidth);
            labelEdgeInsets = UIEdgeInsetsMake(0, -imageWith, -imageHeight-space, 0);
        }
            break;
        case ButtonEdgeInsetsStyleLeft: {
            imageEdgeInsets = UIEdgeInsetsMake(0, -space, 0, space);
            labelEdgeInsets = UIEdgeInsetsMake(0, space, 0, -space);
        }
            break;
        case ButtonEdgeInsetsStyleBottom: {
            imageEdgeInsets = UIEdgeInsetsMake(0, 0, -labelHeight-space, -labelWidth);
            labelEdgeInsets = UIEdgeInsetsMake(-imageHeight-space, -imageWith, 0, 0);
        }
            break;
        case ButtonEdgeInsetsStyleRight: {
            imageEdgeInsets = UIEdgeInsetsMake(0, labelWidth+space, 0, -labelWidth-space);
            labelEdgeInsets = UIEdgeInsetsMake(0, -imageWith-space, 0, imageWith+space);
        }
            break;
        default:
            break;
    }
    // 賦值
    self.titleEdgeInsets = labelEdgeInsets;
    self.imageEdgeInsets = imageEdgeInsets;
}

- (void)setSelected:(BOOL)selected
{
    if (selected) {
        [self setImage:[UIImage imageNamed:self.selectedImageName] forState:UIControlStateNormal];
    }
    else{
         [self setImage:[UIImage imageNamed:self.normalImageName] forState:UIControlStateNormal];
    }
}

- (void)setDefaultImageWithNamed:(NSString *)imgName
{
    [self setImage:[UIImage imageNamed:imgName] forState:UIControlStateNormal];
    self.defaultImageName = imgName;
}

#pragma mark - pravite Method
static const void *normalImageNameKey = &normalImageNameKey;
- (void)setNormalImageName:(NSString *)normalImageName
{
    objc_setAssociatedObject(self, normalImageNameKey, normalImageName,  OBJC_ASSOCIATION_COPY);
}
- (NSString *)normalImageName
{
    return objc_getAssociatedObject(self, normalImageNameKey);
}

static const void *selectedImageNameKey = &selectedImageNameKey;
- (void)setSelectedImageName:(NSString *)selectedImageName
{
    objc_setAssociatedObject(self, selectedImageNameKey, selectedImageName,  OBJC_ASSOCIATION_COPY);
}
- (NSString *)selectedImageName
{
    return objc_getAssociatedObject(self, selectedImageNameKey);
}

static const void *defaultImageNameKey = &defaultImageNameKey;
- (void)setDefaultImageName:(NSString *)defaultImageName
{
    objc_setAssociatedObject(self, defaultImageNameKey, defaultImageName,  OBJC_ASSOCIATION_COPY);
}
- (NSString *)defaultImageName
{
    return objc_getAssociatedObject(self, defaultImageNameKey);
}


#pragma mark - Drawing
- (CGSize)sizeForText:(NSString *)text font:(UIFont *)font size:(CGSize)size mode:(NSLineBreakMode)lineBreakMode {
    CGSize result;
    if (!font) font = [UIFont systemFontOfSize:12];
    if ([self respondsToSelector:@selector(boundingRectWithSize:options:attributes:context:)]) {
        NSMutableDictionary *attr = [NSMutableDictionary new];
        attr[NSFontAttributeName] = font;
        if (lineBreakMode != NSLineBreakByWordWrapping) {
            NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new];
            paragraphStyle.lineBreakMode = lineBreakMode;
            attr[NSParagraphStyleAttributeName] = paragraphStyle;
        }
        CGRect rect = [text boundingRectWithSize:size
                                         options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading
                                      attributes:attr context:nil];
        result = rect.size;
    } else {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
        result = [text sizeWithFont:font constrainedToSize:size lineBreakMode:lineBreakMode];
#pragma clang diagnostic pop
    }
    return result;
}

調(diào)用

#import "ViewController.h"
#import "UIButton+EdgeInsets.h"

@interface ViewController ()

@property (weak, nonatomic) IBOutlet UIButton *buttonTop;
@property (weak, nonatomic) IBOutlet UIButton *buttonBottom;
@property (weak, nonatomic) IBOutlet UIButton *buttonLeft;
@property (weak, nonatomic) IBOutlet UIButton *buttonRight;

@property (weak, nonatomic) IBOutlet UIButton *button4;
@property (weak, nonatomic) IBOutlet UIButton *button5;
@property (weak, nonatomic) IBOutlet UIButton *button6;

@property (assign, nonatomic) BOOL isSelected;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    [self.buttonTop setDefaultImageWithNamed:@"sort_filter_default_img"];
    [self.buttonTop setImagePositionWithEdgeInsetsStyle:ButtonEdgeInsetsStyleTop imageSpace:0];

    [self.buttonBottom setDefaultImageWithNamed:@"sort_filter_default_img"];
    [self.buttonBottom setImagePositionWithEdgeInsetsStyle:ButtonEdgeInsetsStyleBottom imageSpace:0];
    
    [self.buttonLeft setDefaultImageWithNamed:@"sort_filter_default_img"];
    [self.buttonLeft setImagePositionWithEdgeInsetsStyle:ButtonEdgeInsetsStyleLeft imageSpace:5];
    
    [self.buttonRight setDefaultImageWithNamed:@"sort_filter_default_img"];
    [self.buttonRight setImagePositionWithEdgeInsetsStyle:ButtonEdgeInsetsStyleRight imageSpace:5];
    
    [self.button4 setDefaultImageWithNamed:@"sort_filter_asc_img"];
    [self.button4 setSelectedImageName:@"sort_filter_asc_img"];
    [self.button4 setNormalImageName:@"sort_filter_desc_img"];
    [self.button4 setImagePositionWithEdgeInsetsStyle:ButtonEdgeInsetsStyleRight imageSpace:0];
    self.isSelected = YES;
    
    [self.button5 setDefaultImageWithNamed:@"sort_filter_default_img"];
    [self.button5 setImagePositionWithEdgeInsetsStyle:ButtonEdgeInsetsStyleRight imageSpace:0];
    
    [self.button6 setDefaultImageWithNamed:@"sort_filter_default_img"];
    [self.button6 setImagePositionWithEdgeInsetsStyle:ButtonEdgeInsetsStyleRight imageSpace:0];
}

- (IBAction)btn4Action:(UIButton *)sender {
    
    self.isSelected = !self.isSelected;
    sender.selected = self.isSelected;
}

效果


Simulator Screen Shot - iPhone 5s - 2018-05-31 at 11.28.51.png

有需要的同學(xué)可以看看
git地址:https://github.com/destinyzhao/ButtonEdgeInsets

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • UIButton的默認(rèn)顯示樣式是圖片居左,文字居右,如下圖1: 但是有時(shí)候我們根據(jù)需求需要調(diào)整按鈕中圖片和標(biāo)題的位...
    zxFlyer閱讀 1,391評(píng)論 0 7
  • 美團(tuán)iOS面試敗北感悟 | 掘金技術(shù)征文 http://www.cocoachina.com/special/20...
    小劉_假裝是個(gè)程序員閱讀 434評(píng)論 2 0
  • 用到的組件 1、通過CocoaPods安裝 2、第三方類庫(kù)安裝 3、第三方服務(wù) 友盟社會(huì)化分享組件 友盟用戶反饋 ...
    SunnyLeong閱讀 15,205評(píng)論 1 180
  • 自中國(guó)(杭州)跨境電商綜合實(shí)驗(yàn)區(qū)運(yùn)營(yíng)半年多以來,為進(jìn)一步推廣其“六體系兩平臺(tái)”模式,國(guó)務(wù)院于2016年1月15日,...
    Leq閱讀 1,658評(píng)論 0 3
  • 韻聲漫漫 裁剪清脆音 他喚作百靈鳥 在他們相遇的小巷 第一眼 他就情不自禁 那時(shí)她端坐窗前 秀發(fā)烏黑及腰 目光炯炯...
    廖真閱讀 287評(píng)論 0 0

友情鏈接更多精彩內(nèi)容