UIButton的titleEdgeInsets和imageEdgeInsets

dd

之前好不容易弄明白了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ò)。


正值/負(fù)值效果

通過具體應(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為例:


創(chuàng)建button

這里我拖了一個紅色背景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);
label移動

至此圖片和文字調(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);

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

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

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