
之前好不容易弄明白了UIButton的titleEdgeInsets和imageEdgeInsets屬性,然而今天應(yīng)用到的時候又磕磕絆絆的花了好長時間才理清楚。長痛不如短痛,今天就在這里花點時間做個筆記,同時希望可以方便不了解這兩個屬性用法的伙伴有所理解。
我們知道UIButton由一個titleLabel和imageView組成的,顯而易見titleEdgeInsets和imageEdgeInsets分別對應(yīng)著UIButton中的titleLabel和imageView。這兩個屬性是UIEdgeInsets結(jié)構(gòu)體:
typedef struct UIEdgeInsets {
CGFloat top, left, bottom, right; // specify amount to inset (positive) for each of the edges. values can be negative to 'outset'
} UIEdgeInsets;
titleEdgeInsets和imageEdgeInsets作用類似于UIScrollView的contentInset(UIButton也有contentEdgeInsets),top,left,bottom,right分別設(shè)置距離上左下右邊的內(nèi)邊距,默認(rèn)都為0。這里要說明下top,left,bottom,right正負(fù)值的情況,正值是向內(nèi)縮,負(fù)值向外擴(kuò)。

通過具體應(yīng)用場景來分析下:
應(yīng)用場景1: UIButton圖片的大小
設(shè)置button圖片的時候(非背景圖片backgroundImage),當(dāng)設(shè)置的圖片本身的size比button的size要大時,默認(rèn)情況下圖片會填充整個button。這時有這樣的需求:button的大小不變但圖片需要調(diào)小(一般是為了讓button在界面顯示大小適中,但點擊的范圍又要盡量大),而button的imageView的frame設(shè)置是無效的。一個解決方法是把原圖切小到符合要求的尺寸,再設(shè)置圖片。另一個簡單的方法就是設(shè)置imageEdgeInsets。
button的size為100x100,設(shè)置的圖片size也是100x100。我們可以設(shè)置button. imageEdgeInsets = UIEdgeInsetsMake(25, 25, 25, 25)來達(dá)到縮小圖片的目的。這樣button看起來只有50x50大,但實際圖片上下左右25范圍內(nèi)仍能觸發(fā)點擊事件。(一些新手是這樣實現(xiàn)的:創(chuàng)建了一個100x100的透明的button,然后創(chuàng)建50x50的imageView添加到button上)
應(yīng)用場景2:調(diào)整titleLabel和imageView的相對位置
我們知道UIButton的默認(rèn)布局是圖片在左,文字在右的。但很多情況下,需求都要求圖片在右文字在左,或者圖片文字為上下布局。很多小伙伴都沖動的直接去自定義button了,同樣我們只要設(shè)置titleEdgeInsets和imageEdgeInsets就能簡單的實現(xiàn)這樣的需求。我們以一個demo為例:

這里我拖了一個紅色背景100x100的button,設(shè)置的圖片為50x50。默認(rèn)情況titleEdgeInsets和imageEdgeInsets都為0?,F(xiàn)在我們要把圖片和文字調(diào)換過來,前面的場景是調(diào)整了圖片的大小,現(xiàn)在調(diào)換位置其實原理是一樣的。因為都是左右移動,那么上下邊距就不用調(diào)節(jié)。圖片需要右移,也就是圖片左邊left往內(nèi)縮右邊right往外擴(kuò)。前面說了正值是內(nèi)縮,負(fù)值是向外擴(kuò),現(xiàn)在就可以確定imageEdgeInsets的left為正right需為負(fù)。具體數(shù)值可以通過titleLabel的frame確定:
CGFloat labelW = _button.titleLabel.frame.size.width;
_button.imageEdgeInsets = UIEdgeInsetsMake(0, labelW, 0, -labelW);

同樣的文字需要左移,也就是文字左邊left為負(fù)往外擴(kuò)右邊right為正往內(nèi)縮:
CGFloat imageW = _button.imageView.frame.size.width;
_button.titleEdgeInsets = UIEdgeInsetsMake(0, -imageW, 0, imageW);

至此圖片和文字調(diào)換過來了,它們的frame也改變了:
(lldb) po _button.imageView.frame.origin.x
39.333333333333343
(lldb) po _button.titleLabel.frame.origin.x
10.666666666666666
圖片和文字為上下布局時,也是類似的調(diào)整,只是設(shè)置的就是top和bottom了。
從上面兩個場景可以總結(jié)出,設(shè)置titleEdgeInsets和imageEdgeInsets能實現(xiàn)button的titleLabel和imageView的縮放及平移。
針對titleLabel和imageView的各種不同位置,我們可以簡單封裝下:
typedef NS_ENUM(NSInteger, ButtonImageTitleStyle ) {
ButtonImageTitleStyleDefault , //圖片在左,文字在右,整體居中。
ButtonImageTitleStyleLeft, //圖片在左,文字在右,整體居中。
ButtonImageTitleStyleRight, //圖片在右,文字在左,整體居中。
ButtonImageTitleStyleTop, //圖片在上,文字在下,整體居中。
ButtonImageTitleStyleBottom, //圖片在下,文字在上,整體居中。
ButtonImageTitleStyleCenterTop, //圖片居中,文字在上距離按鈕頂部。
ButtonImageTitleStyleCenterBottom, //圖片居中,文字在下距離按鈕底部。
ButtonImageTitleStyleCenterUp, //圖片居中,文字在圖片上面。
ButtonImageTitleStyleCenterDown, //圖片居中,文字在圖片下面。
ButtonImageTitleStyleRightLeft, //圖片在右,文字在左,距離按鈕兩邊邊距
ButtonImageTitleStyleLeftRight, //圖片在左,文字在右,距離按鈕兩邊邊距
};
@interface UIButton (ImageTitleStyle)
/*
調(diào)整按鈕的文本和image的布局
padding是調(diào)整布局時整個按鈕和圖文的間隔。
(前提是title和image同時存在才會調(diào)整)
*/
- (void)setButtonImageTitleStyle:(ButtonImageTitleStyle)style padding:(CGFloat)padding;
@end
#import "UIButton+ImageTitleStyle.h"
@implementation UIButton (ImageTitleStyle)
- (void)setButtonImageTitleStyle:(ButtonImageTitleStyle)style padding:(CGFloat)padding
{
if (self.imageView.image != nil && self.titleLabel.text != nil)
{
//先還原
self.titleEdgeInsets = UIEdgeInsetsZero;
self.imageEdgeInsets = UIEdgeInsetsZero;
CGRect imageRect = self.imageView.frame;
CGRect titleRect = self.titleLabel.frame;
CGFloat totalHeight = imageRect.size.height + padding + titleRect.size.height;
CGFloat selfHeight = self.frame.size.height;
CGFloat selfWidth = self.frame.size.width;
switch (style) {
case ButtonImageTitleStyleLeft:
if (padding != 0)
{
self.titleEdgeInsets = UIEdgeInsetsMake(0,
padding/2,
0,
-padding/2);
self.imageEdgeInsets = UIEdgeInsetsMake(0,
-padding/2,
0,
padding/2);
}
break;
case ButtonImageTitleStyleRight:
{
//圖片在右,文字在左
self.titleEdgeInsets = UIEdgeInsetsMake(0,
-(imageRect.size.width + padding/2),
0,
(imageRect.size.width + padding/2));
self.imageEdgeInsets = UIEdgeInsetsMake(0,
(titleRect.size.width+ padding/2),
0,
-(titleRect.size.width+ padding/2));
}
break;
case ButtonImageTitleStyleTop:
{
//圖片在上,文字在下
self.titleEdgeInsets = UIEdgeInsetsMake(((selfHeight - totalHeight)/2 + imageRect.size.height + padding - titleRect.origin.y),
(selfWidth/2 - titleRect.origin.x - titleRect.size.width /2) - (selfWidth - titleRect.size.width) / 2,
-((selfHeight - totalHeight)/2 + imageRect.size.height + padding - titleRect.origin.y),
-(selfWidth/2 - titleRect.origin.x - titleRect.size.width /2) - (selfWidth - titleRect.size.width) / 2);
self.imageEdgeInsets = UIEdgeInsetsMake(((selfHeight - totalHeight)/2 - imageRect.origin.y),
(selfWidth /2 - imageRect.origin.x - imageRect.size.width / 2),
-((selfHeight - totalHeight)/2 - imageRect.origin.y),
-(selfWidth /2 - imageRect.origin.x - imageRect.size.width / 2));
}
break;
case ButtonImageTitleStyleBottom:
{
//圖片在下,文字在上。
self.titleEdgeInsets = UIEdgeInsetsMake(((selfHeight - totalHeight)/2 - titleRect.origin.y),
(selfWidth/2 - titleRect.origin.x - titleRect.size.width / 2) - (selfWidth - titleRect.size.width) / 2,
-((selfHeight - totalHeight)/2 - titleRect.origin.y),
-(selfWidth/2 - titleRect.origin.x - titleRect.size.width / 2) - (selfWidth - titleRect.size.width) / 2);
self.imageEdgeInsets = UIEdgeInsetsMake(((selfHeight - totalHeight)/2 + titleRect.size.height + padding - imageRect.origin.y),
(selfWidth /2 - imageRect.origin.x - imageRect.size.width / 2),
-((selfHeight - totalHeight)/2 + titleRect.size.height + padding - imageRect.origin.y),
-(selfWidth /2 - imageRect.origin.x - imageRect.size.width / 2));
}
break;
case ButtonImageTitleStyleCenterTop:
{
self.titleEdgeInsets = UIEdgeInsetsMake(-(titleRect.origin.y - padding),
(selfWidth / 2 - titleRect.origin.x - titleRect.size.width / 2) - (selfWidth - titleRect.size.width) / 2,
(titleRect.origin.y - padding),
-(selfWidth / 2 - titleRect.origin.x - titleRect.size.width / 2) - (selfWidth - titleRect.size.width) / 2);
self.imageEdgeInsets = UIEdgeInsetsMake(0,
(selfWidth / 2 - imageRect.origin.x - imageRect.size.width / 2),
0,
-(selfWidth / 2 - imageRect.origin.x - imageRect.size.width / 2));
}
break;
case ButtonImageTitleStyleCenterBottom:
{
self.titleEdgeInsets = UIEdgeInsetsMake((selfHeight - padding - titleRect.origin.y - titleRect.size.height),
(selfWidth / 2 - titleRect.origin.x - titleRect.size.width / 2) - (selfWidth - titleRect.size.width) / 2,
-(selfHeight - padding - titleRect.origin.y - titleRect.size.height),
-(selfWidth / 2 - titleRect.origin.x - titleRect.size.width / 2) - (selfWidth - titleRect.size.width) / 2);
self.imageEdgeInsets = UIEdgeInsetsMake(0,
(selfWidth / 2 - imageRect.origin.x - imageRect.size.width / 2),
0,
-(selfWidth / 2 - imageRect.origin.x - imageRect.size.width / 2));
}
break;
case ButtonImageTitleStyleCenterUp:
{
self.titleEdgeInsets = UIEdgeInsetsMake(-(titleRect.origin.y + titleRect.size.height - imageRect.origin.y + padding),
(selfWidth / 2 - titleRect.origin.x - titleRect.size.width / 2) - (selfWidth - titleRect.size.width) / 2,
(titleRect.origin.y + titleRect.size.height - imageRect.origin.y + padding),
-(selfWidth / 2 - titleRect.origin.x - titleRect.size.width / 2) - (selfWidth - titleRect.size.width) / 2);
self.imageEdgeInsets = UIEdgeInsetsMake(0,
(selfWidth / 2 - imageRect.origin.x - imageRect.size.width / 2),
0,
-(selfWidth / 2 - imageRect.origin.x - imageRect.size.width / 2));
}
break;
case ButtonImageTitleStyleCenterDown:
{
self.titleEdgeInsets = UIEdgeInsetsMake((imageRect.origin.y + imageRect.size.height - titleRect.origin.y + padding),
(selfWidth / 2 - titleRect.origin.x - titleRect.size.width / 2) - (selfWidth - titleRect.size.width) / 2,
-(imageRect.origin.y + imageRect.size.height - titleRect.origin.y + padding),
-(selfWidth / 2 - titleRect.origin.x - titleRect.size.width / 2) - (selfWidth - titleRect.size.width) / 2);
self.imageEdgeInsets = UIEdgeInsetsMake(0,
(selfWidth / 2 - imageRect.origin.x - imageRect.size.width / 2),
0,
-(selfWidth / 2 - imageRect.origin.x - imageRect.size.width / 2));
}
break;
case ButtonImageTitleStyleRightLeft:
{
//圖片在右,文字在左,距離按鈕兩邊邊距
self.titleEdgeInsets = UIEdgeInsetsMake(0,
-(titleRect.origin.x - padding),
0,
(titleRect.origin.x - padding));
self.imageEdgeInsets = UIEdgeInsetsMake(0,
(selfWidth - padding - imageRect.origin.x - imageRect.size.width),
0,
-(selfWidth - padding - imageRect.origin.x - imageRect.size.width));
}
break;
case ButtonImageTitleStyleLeftRight:
{
//圖片在左,文字在右,距離按鈕兩邊邊距
self.titleEdgeInsets = UIEdgeInsetsMake(0,
(selfWidth - padding - titleRect.origin.x - titleRect.size.width),
0,
-(selfWidth - padding - titleRect.origin.x - titleRect.size.width));
self.imageEdgeInsets = UIEdgeInsetsMake(0,
-(imageRect.origin.x - padding),
0,
(imageRect.origin.x - padding));
}
break;
default:
break;
}
}
else {
self.titleEdgeInsets = UIEdgeInsetsMake(0, 0, 0, 0);
self.imageEdgeInsets = UIEdgeInsetsMake(0, 0, 0, 0);
}
}
@end
UIButton還有contentEdgeInsets,設(shè)置后對圖片文字都生效的。
_button.contentEdgeInsets = UIEdgeInsetsMake(20, 0, 0, 0);
