iOS自定義按鈕button詳解封裝說明

iOS常用到有標題同時有圖片的按鈕蟹演,但是系統(tǒng)控件默認只提供圖片在左阴颖,標題在右的樣式,想要其他的樣式就需要自己處理云头,常用的處理方式有兩種捐友。
一種是設置兩個UIEdgeInsets屬性

@property(nonatomic)          UIEdgeInsets titleEdgeInsets;
@property(nonatomic)          UIEdgeInsets imageEdgeInsets; 

相信用過這兩個設置的都知道,按鈕用這兩個設置很難找準位置溃槐。
另外一種是兩個接口

- (CGRect)titleRectForContentRect:(CGRect)contentRect;
- (CGRect)imageRectForContentRect:(CGRect)contentRect;

兩個接口可以分別設置圖片和標題的位置匣砖。效果圖

圖片在右.png
圖片在左.png
圖片在上.png
圖片在下.png

為了方便使用一般都會封裝一個UIButton的子類,寫一個結構體作為圖片和標題相對位置的設置選擇和內部處理判斷。

typedef enum {
    imageTop = 0,   // 圖片上 標題下
    imageLeft,      // 圖片左 標題右
    imageBottom,    // 圖片下 標題上
    imageRight,     // 圖片右 標題左
} ImageStyle;
- (CGRect)imageRectForContentRect:(CGRect)contentRect{
    if (self.buttonStyle == imageRight) {
        return [self imageRectWithImageRightForContentTect:contentRect];
    }
    else if (self.buttonStyle == imageTop){
        return [self imageRectWithImageTopForContentTect:contentRect];
    }
    else if (self.buttonStyle == imageBottom){
        return [self imageRectWithImageBottomForContentTect:contentRect];
    }
    else {
        return [self imageRectWithImageLeftForContentTect:contentRect];
    }

}

- (CGRect)titleRectForContentRect:(CGRect)contentRect{
    if (self.buttonStyle == imageRight) {
        return [self titleRectWithImageRightForContentTect:contentRect];
    }
    else if (self.buttonStyle == imageTop){
        return [self titleRectWithImageTopForContentTect:contentRect];
    }
    else if (self.buttonStyle == imageBottom){
        return [self titleRectWithImageBottomForContentTect:contentRect];
    }
    else {
        return [self titleRectWithImageLeftForContentTect:contentRect];
    }
}

初始化方法中做一些默認設置,設置font是因為在處理方法中用于判斷標題的長度或者寬度猴鲫,按說系統(tǒng)一定有默認值的砌溺,但是不設置就是獲取不到,所以這里做了默認的設置变隔。

- (instancetype)initWithFrame:(CGRect)frame{
    self = [super initWithFrame:frame];
    if (self) {
        self.titleLabel.font = titleFont;
        self.buttonStyle = imageLeft;
        self.titleLabel.textAlignment = NSTextAlignmentCenter;
    }
    
    return self;
}

- (instancetype)init{
    self = [super init];
    if (self) {
        self.titleLabel.font = titleFont;
        self.buttonStyle = imageLeft;
        self.titleLabel.textAlignment = NSTextAlignmentCenter;
    }
    
    return self;
}

常用情況下按鈕都不會占滿按鈕高度或者寬度规伐,而且多為正方形,所以在處理的時候左右布局時給圖片的尺寸定位按鈕高度的0.6匣缘,上下布局時為按鈕1/2高度的0.6猖闪。具體到有特殊需求的時候都可以調整。貼出圖片在右和圖片在上的兩個處理代碼肌厨。

#pragma mark imageRight 圖片在右 文字在左
- (CGRect)imageRectWithImageRightForContentTect:(CGRect)contentRect{
    CGFloat imageWH = CGRectGetHeight(contentRect)*scale;
    CGFloat inteval = (CGRectGetHeight(contentRect)-imageWH)/2;
    CGFloat titleW = [self widthForTitleString:[self titleForState:UIControlStateNormal] ContentRect:contentRect];
    CGFloat titleX = (CGRectGetWidth(contentRect)-titleW-imageWH)/2;
    if (titleX < 0) {
        titleX = 0;
    }
    CGRect rect = CGRectMake(titleX+titleW , inteval, imageWH, imageWH);
    
    return rect;
}

- (CGRect)titleRectWithImageRightForContentTect:(CGRect)contentRect{
    CGFloat imageWH = CGRectGetHeight(contentRect)*scale;
    CGFloat titleW = [self widthForTitleString:[self titleForState:UIControlStateNormal] ContentRect:contentRect];
    CGFloat titleX = (CGRectGetWidth(contentRect)-titleW-imageWH)/2;
    if (titleX < 0) {
        titleX = 0;
    }
    CGRect rect = CGRectMake(titleX, 0, titleW , CGRectGetHeight(contentRect));
    
    return rect;
}
#pragma mark imageTop 圖片在上 文字在下
- (CGRect)imageRectWithImageTopForContentTect:(CGRect)contentRect{
    CGFloat imageWH = CGRectGetHeight(contentRect)/2*scale;
    CGFloat titleH = [self heightForTitleString:[self titleForState:UIControlStateNormal] ContentRect:contentRect];
    CGFloat imageY = (CGRectGetHeight(contentRect)-imageWH-titleH)/2;
    CGFloat imageX = (CGRectGetWidth(contentRect) - imageWH)/2;
    CGRect rect = CGRectMake(imageX, imageY, imageWH, imageWH);
    
    return rect;
}

- (CGRect)titleRectWithImageTopForContentTect:(CGRect)contentRect{
    CGFloat imageWH = CGRectGetHeight(contentRect)/2*scale;
    CGFloat titleH = [self heightForTitleString:[self titleForState:UIControlStateNormal] ContentRect:contentRect];
    CGFloat titleY = (CGRectGetHeight(contentRect)-imageWH-titleH)/2+imageWH;;
    
    CGRect rect = CGRectMake(0, titleY, CGRectGetWidth(contentRect) , titleH);
    
    return rect;
}
#pragma mark 計算標題內容寬度
- (CGFloat)widthForTitleString:(NSString *)string ContentRect:(CGRect)contentRect{
   if (string) {
        CGSize constraint = contentRect.size;
        NSAttributedString* attributedText = [[NSAttributedString alloc] initWithString:string attributes:@{NSFontAttributeName: self.titleLabel.font}];
        CGRect rect = [attributedText boundingRectWithSize:constraint options:NSStringDrawingUsesLineFragmentOrigin context:nil];
        CGSize size = rect.size;
        CGFloat width = MAX(size.width, 30);
        CGFloat imageW = [self imageForState:UIControlStateNormal].size.width;

        if (width+imageW > CGRectGetWidth(contentRect)) { // 當標題和圖片寬度超過按鈕寬度時不能越界
           return  CGRectGetWidth(contentRect) - imageW;
        }
        return width+10;
    }
    else {
        return CGRectGetWidth(contentRect)/2;
    }
}

#pragma mark 計算標題文字內容的高度
- (CGFloat)heightForTitleString:(NSString *)string ContentRect:(CGRect)contentRect{
    if (string) {
        CGSize constraint = contentRect.size;
        NSAttributedString* attributedText = [[NSAttributedString alloc] initWithString:string attributes:@{NSFontAttributeName: self.titleLabel.font}];
        CGRect rect = [attributedText boundingRectWithSize:constraint options:NSStringDrawingUsesLineFragmentOrigin context:nil];
        CGSize size = rect.size;
        CGFloat height = MAX(size.height, 5);
        
        if (height > CGRectGetHeight(contentRect)/2) { // 當標題高度超過按鈕1/2寬度時
            return  CGRectGetHeight(contentRect)/2 ;
        }
        return height;
    }
    else {
        return CGRectGetHeight(contentRect)/2;
    }
}

如此培慌,初始化的時候只需要設置下按鈕樣式即可,默認是圖片在左柑爸。

 MCButton *button = [[MCButton alloc] initWithFrame:CGRectMake(50, 50, 100, 50)];
    button.buttonStyle = imageBottom;
    button.titleLabel.font = [UIFont systemFontOfSize:15.0];
    [button setTitle:@"測試按鈕" forState:UIControlStateNormal];
    [button setBackgroundColor:[UIColor lightGrayColor]];
    [button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
    [button setImage:[UIImage imageNamed:@"點評_icon_評論"] forState:UIControlStateNormal];

    [self.view addSubview:button];

demo地址 GitHub給個Star噢!
喜歡就點個贊唄!
歡迎大家提出更好的改進意見和建議吵护,一起進步!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末表鳍,一起剝皮案震驚了整個濱河市馅而,隨后出現的幾起案子,更是在濱河造成了極大的恐慌譬圣,老刑警劉巖瓮恭,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異厘熟,居然都是意外死亡屯蹦,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門绳姨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來登澜,“玉大人,你說我怎么就攤上這事飘庄∧匀洌” “怎么了?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵竭宰,是天一觀的道長空郊。 經常有香客問我,道長切揭,這世上最難降的妖魔是什么狞甚? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮廓旬,結果婚禮上哼审,老公的妹妹穿的比我還像新娘谐腰。我一直安慰自己,他們只是感情好涩盾,可當我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布十气。 她就那樣靜靜地躺著,像睡著了一般春霍。 火紅的嫁衣襯著肌膚如雪砸西。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天址儒,我揣著相機與錄音芹枷,去河邊找鬼。 笑死莲趣,一個胖子當著我的面吹牛鸳慈,可吹牛的內容都是我干的。 我是一名探鬼主播喧伞,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼走芋,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了潘鲫?” 一聲冷哼從身側響起翁逞,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎次舌,沒想到半個月后熄攘,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡彼念,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了浅萧。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片逐沙。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖洼畅,靈堂內的尸體忽然破棺而出吩案,到底是詐尸還是另有隱情,我是刑警寧澤帝簇,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布徘郭,位于F島的核電站,受9級特大地震影響丧肴,放射性物質發(fā)生泄漏残揉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一芋浮、第九天 我趴在偏房一處隱蔽的房頂上張望抱环。 院中可真熱鬧,春花似錦、人聲如沸镇草。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽梯啤。三九已至竖伯,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間因宇,已是汗流浹背黔夭。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留羽嫡,地道東北人本姥。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像杭棵,于是被迫代替她去往敵國和親婚惫。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內容