iOS中UIButton實現(xiàn)各種圖文結(jié)合的效果以及原理

iOS的UIButton是一個非常常見而且常用的控件,我們一般用他來實現(xiàn)某個功能的提交以及選擇操作扼倘。我們可以建立只有文字的Button钧惧,也可以建立只有圖片的Button,具體的需求要看界面設(shè)計的具體情況护桦。有時候我們希望應(yīng)用的界面元素是豐富多彩的,有時候希望建立一個圖文結(jié)合的控件來響應(yīng)用戶的手勢操作煎娇,因此建立一個即有圖片也有文字的按鈕來實現(xiàn)功能二庵,這個只需要分別調(diào)用UIButton的setTitle:forState:setImage:forSate:兩個方法就可以實現(xiàn)具有圖片和文字功能的按鈕

但是系統(tǒng)默認(rèn)的圖文結(jié)合的按鈕布局是:圖片在左邊而文字在右邊缓呛,而且整體水平和垂直居中催享。
比如下面這個圖文按鈕:

系統(tǒng)默認(rèn)的圖文結(jié)合的按鈕布局

但是有的時候我們又希望圖片在右邊而文字在左邊;或者圖片在上邊而文字在下面哟绊;或者圖片在按鈕的中間而文字在圖片的下面等等因妙,但我們又不想放棄使用按鈕這個控件,這時候怎么辦? 事件總是能找到解決方法的兰迫, 有的人會先建立一個按鈕控件鋪在下面,而在上面分別覆蓋一個UIImageViewUILabel來實現(xiàn)炬称;而有的人則干脆在UIButton上建立一個UIImageViewUILabel兩個子視圖汁果;而有的人則不會用UIButton來實現(xiàn)圖文結(jié)合的功能。 前面說的幾個方法看起來有效玲躯,也確實會解決問題据德,但缺點是代碼量會增加,而且必須同時管理UIButton, UIImageView, UILabel這三個整體跷车,如果哪天產(chǎn)品還希望有一個按鈕按下高亮或者按下陰影效果時,你可能又要重新編寫代碼實現(xiàn)需求了棘利。

那么我們是否要放棄 UIButton 呢?答案是否定的朽缴,其實 UIButton 本身是可以支持各種圖文結(jié)合的善玫,既然 UIButton 上能同時顯示圖片和文字,那就可以肯定的說 UIButton 里面本身一定有一個 UIImageView 和 UILabel 子視圖密强。 UIButton本身就是一個復(fù)合控件茅郎,他分別提供了兩個屬性:

@property(nonatomic,readonly,retain)UILabel     *titleLabel NS_AVAILABLE_IOS(3_0);
@property(nonatomic,readonly,retain)UIImageView *imageView  NS_AVAILABLE_IOS(3_0);

需要注意的是這兩個屬性必須要調(diào)用完setTitle:forSate:setImage:forSate:后才能獲取到,否則有可能會返回nil或渤。

其中的 titleLabel是用來保存文字的系冗,而imageView是用來保存圖片的。那既然UIButton本身就帶有一個圖片控件和文本控件薪鹦,那是不是我們只要分別通過調(diào)整子控件的frame值就能實現(xiàn)我們想要的圖片文字的任何布局呢掌敬? 答案是否定的。實驗證明通過設(shè)置 titleLabel池磁、imageView 的 frame 值根本不會改變按鈕里面圖片在左而文字在右的格局奔害。 要想實現(xiàn)功能就必須使用另外兩個屬性(titleEdgeInsets、imageEdgeInsets):

@property(nonatomic)         UIEdgeInsets titleEdgeInsets;   // default is UIEdgeInsetsZero
@property(nonatomic)         UIEdgeInsets imageEdgeInsets;   // default is UIEdgeInsetsZero

這兩個屬性是分別用來調(diào)整按鈕中文本的偏移縮進(jìn)以及圖片的偏移縮進(jìn)的地熄,他們都是一個UIEdgeInsets 對象舀武,默認(rèn)的值都是0

也就是默認(rèn)的值都是0的情況下按鈕的圖片和文字垂直居中离斩,而且圖片在左邊文字在右邊银舱,而且圖片文本整體水平居中

而我們則可以通過調(diào)整 titleEdgeInsetsimageEdgeInsets 的值來實現(xiàn)我們想要的任何圖文布局的情況跛梗,甚至我們希望圖片和文字之間還要保留一些間隔的情況寻馏。怎么調(diào)整? 調(diào)整多少為最合適核偿?

在調(diào)整之前我們先定義幾個特定的變量值:

CGRect titleRect = titleLabel.frame;        //文本控件在按鈕中的frame值诚欠。
CGRect imageRect = imageView.frame;  //圖片控件在按鈕中的frame值。
CGFloat padding;                                     //用于指定文本和圖片的間隔值。
CGFloat selfWidth;                                   //按鈕控件的寬度
CGFloat selfHeight;                                  //按鈕控件的高度
CGFloat totalHeight=titleRect.size.height+padding+imageRect.size.height;  //圖文上下布局時所占用的總高度轰绵,注意這里也算上他們之間的間隔值padding

我們可以通過更改按鈕的titleEdgeInsetsimageEdgeInsets的值調(diào)整文本和圖片的位置粉寞。如果我們想往右移動20的話,那么就應(yīng)該同時設(shè)置 UIEdgeInsets 的 left = 20, right = -20 左腔,而如果我們想 往上移動20 的話唧垦,那么就應(yīng)該應(yīng)該同時設(shè)置 UIEdgeInsets 的 top = -20 ,bottom = 20。下面我們就分別通過調(diào)整按鈕的titleEdgeInsetsimageEdgeInsets的值來實現(xiàn)各種圖文結(jié)合的效果:

一液样、圖片在左振亮,文字在右,整體居中鞭莽,調(diào)整間距

圖片在左坊秸,文字在右,整體居中澎怒,調(diào)整間距

這種方式是按鈕默認(rèn)的圖文布局方式褒搔,因為要調(diào)整圖片和文本的間距,所以只需要 文本右移 padding/2.0 喷面,而 圖片左移 padding/2.0 值就可以了站超。設(shè)置的代碼為:

//上、左乖酬、下死相、右
//padding 用于指定文本和圖片的間隔值
  titleEdgeInsets =UIEdgeInsetsMake(0, padding/2.0 , 0,  -padding/2.0 );

  imageEdgeInsets = UIEdgeInsetsMake(0,  -padding/2.0 , 0 , padding/2.0 );

二、圖片在右咬像,文字在左算撮,整體居中

圖片在右,文字在左县昂,整體居中

要實現(xiàn)這種布局只需要將文字往左偏移圖片的寬度并且再往左偏移 padding/2.0就可以了肮柜,而圖片則只需要往右偏移文本的寬度并再往右偏移 padding/2.0就可以了。設(shè)置的代碼為:

//上倒彰、左审洞、下、右
 //titleRect  //文本控件在按鈕中的frame值待讳。
 //imageRect  //圖片控件在按鈕中的frame值芒澜。
 //padding     //用于指定文本和圖片的間隔值。

  titleEdgeInsets =UIEdgeInsetsMake(0, -(imageRect.size.width + padding/2.0), 
                                          0,(imageRect.size.width + padding/2.0));

  imageEdgeInsets =UIEdgeInsetsMake(0,(titleRect.size.width+ padding/2.0),
                                       0, -(titleRect.size.width+ padding/2.0));

三创淡、圖片在上痴晦,文字在下,整體居中

圖片在上琳彩,文字在下誊酌,整體居中

這種布局下當(dāng) 圖片和文字要求垂直居中 后:

titleRect //文本控件在按鈕中的frame值部凑。
imageRect //圖片控件在按鈕中的frame值。
padding //用于指定文本和圖片的間隔值碧浊。
selfWidth //按鈕控件的寬度
selfHeight //按鈕控件的高度
totalHeight=titleRect.size.height+padding+imageRect.size.height; //圖文上下布局

  • 新的圖片的頂部位置應(yīng)該等于(selfHeight - totalHeight)/2.0涂邀, 因此垂直需要偏移的值就是新的位置 減去原來的位置 imageRect.origin.y

  • 而新的圖片的水平中心點要等于 selfWidth/2.0 箱锐,而原來的圖片的水平中心點等于imageRect.origin.x + imageRect.size.width/2.0比勉,兩者相減就是水平需要偏移的值。

也可以理解為:新的圖片的左邊位置應(yīng)該等于(selfWidth - imageRect.size.width)/2.0瑞躺, 因此 水平方向 需要偏移的值就是新的位置 減去原來的位置imageRect.origin.x

  • 而新的文本的水平中心點也是 selfWidth/2.0兴想,而原來的文本的水平中心點是titleRect.origin.x + titleRect.size.width/2.0幢哨, 兩者相減就是水平需要偏移的值,又因為默認(rèn)的情況下當(dāng)按鈕比較小時會自動保留圖片的尺寸和將文字部分縮小嫂便,因此當(dāng)我們實現(xiàn)文字和圖片上下布局時捞镰,需要將文字的區(qū)域擴展到整個按鈕部分,否則將會縮小按鈕的文字的寬度毙替,因此按鈕的寬度為selfWidth, 而文字的默認(rèn)寬度是titleRect.size.width,所以上面的實現(xiàn)將文本移到中間后還需要分別向兩邊進(jìn)行拉伸(selfWidth - titleRect.size.width)/2.0來保證文本填充滿所有的按鈕區(qū)域 岸售,在下面的各種樣式中凡是文字和圖片垂直居中的情況下都要考慮這種情況 設(shè)置的代碼為:
imageEdgeInsets =UIEdgeInsetsMake((selfHeight - totalHeight)/2.0 - imageRect.origin.y,
                       selfWidth/2.0 - imageRect.size.width/2.0 - imageRect.origin.x,
                 -((selfHeight - totalHeight)/2.0 - imageRect.origin.y),
                 -(selfWidth /2.0 - imageRect.origin.x - imageRect.size.width /2.0));

  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);



四、圖片在下厂画,文字在上凸丸,整體居中

圖片在下,文字在上袱院,整體居中

這種布局就是上面的文字和圖片位置調(diào)換屎慢,因此設(shè)置代碼為:


  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);

  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));

五、圖片保持居中忽洛,而文字左右居中且頂部距離按鈕頂部

圖片保持居中腻惠,而文字左右居中且頂部距離按鈕頂部

這種方式要求圖片在按鈕中居中,而文字則要求左右居中而垂直方向位置則是距離按鈕頂部的間隔值欲虚。 上面因為描述了水平居中的調(diào)整集灌,因此這里就不介紹了,只介紹垂直方向的調(diào)整复哆。 因為要求圖片要垂直居中欣喧,因此不需要調(diào)整垂直偏移。而文本則要調(diào)整為距離頂部的間隔值梯找,也就是新的文本的頂部值等于padding, 而原來頂部值是titleRect.origin.y续誉,因此只需要偏移titleRect.origin.y - padding就可以了吩谦。設(shè)置代碼為:

  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);

  imageEdgeInsets =UIEdgeInsetsMake(0,
                                     (selfWidth /2 - imageRect.origin.x - imageRect.size.width /2),
                                     0,
                                     -(selfWidth /2 - imageRect.origin.x - imageRect.size.width /2));

六溉箕、圖片保持居中择卦,而文字水平居中且底部距離按鈕底部

圖片保持居中,而文字水平居中且底部距離按鈕底部

這種方式要求圖片在按鈕居中抡爹,而文字則要求左右居中而垂直方向的底部位置則是距離按鈕底部的間隔值。圖片的調(diào)整上面有介紹寥假,而文字的水平調(diào)整上面也有說到盲泛,這里面只說文字的垂直調(diào)整。文字新的底部位置等于selfHeight - padding, 而舊的底部位置是titleRect.size.height + titleRect.origin.y摔握, 因此要偏移的位置就是兩者相減的值寄狼。代碼的設(shè)置為:

  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);

  imageEdgeInsets =UIEdgeInsetsMake(0,
                                     (selfWidth /2 - imageRect.origin.x - imageRect.size.width /2),
                                     0,
                                     -(selfWidth /2 - imageRect.origin.x - imageRect.size.width /2));

七、圖片保持居中氨淌,而文字水平居中并且在圖片的上面

圖片保持居中泊愧,而文字水平居中并且在圖片的上面

這種方式要求圖片在按鈕居中,而文字則要求左右居中并且在垂直在圖片的上面并保留出padding的間隔盛正。 圖片的偏移上面有說到删咱,而文字的水平偏移上面也有說到,這里只說垂直偏移豪筝,文字新的底部位置等于圖片的頂部位置 - padding 而文字老的底部位置等于titleRect.size.height + titleRect.origin.y, 因此兩者的差值就是文字需要垂直偏移的值痰滋。代碼設(shè)置為:


  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);

  imageEdgeInsets =UIEdgeInsetsMake(0,
                                     (selfWidth /2 - imageRect.origin.x - imageRect.size.width /2),
                                     0,
                                     -(selfWidth /2 - imageRect.origin.x - imageRect.size.width /2));

八、圖片保持居中续崖,而文字水平居中并且在圖片的下面

圖片保持居中敲街,而文字水平居中并且在圖片的下面

這種方式要求圖片在按鈕居中,而文字則要求左右居中并且垂直在圖片的下面并保留出padding的間隔严望。圖片的偏移上面有說到多艇,而文字的水平偏移上面也有說到,這里只說垂直偏移像吻,文字新的頂部位置等于imageRect.origin.y + imageRect.size.height + padding, 而文字老的頂部位置等于titleRect.origin.y墩蔓,因此兩者的差值就是文字需要垂直偏移的值。代碼設(shè)置為:


  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);

  imageEdgeInsets =UIEdgeInsetsMake(0,
                                     (selfWidth /2 - imageRect.origin.x - imageRect.size.width /2),
                                     0,
                                     -(selfWidth /2 - imageRect.origin.x - imageRect.size.width /2));

九萧豆、圖片在右奸披,文字在左,距離按鈕兩邊邊距

圖片在右涮雷,文字在左阵面,距離按鈕兩邊邊距

在這種方式中,圖片和文本都是垂直居中對齊洪鸭,這部分是不需要調(diào)整的样刷,而文本的左邊則需要由原來的titleRect.origin.x移動到左邊padding的位置,而圖片的左邊則需要由原來的imageRect.origin.x移動到selfWidth - padding - imageRect.size.width位置览爵。因此代碼設(shè)置為:

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));

十置鼻、圖片在左,文字在右蜓竹,距離按鈕兩邊邊距

圖片在左箕母,文字在右储藐,距離按鈕兩邊邊距

這種方式中,圖片和文字的垂直位置不需要調(diào)整嘶是,而只需要將圖文的水平位置調(diào)整即可钙勃,而調(diào)整的方法和上面的相似,只是圖片移到左邊兒文字移到右邊而已聂喇。代碼設(shè)置為:

 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));

前面說的的十種圖文結(jié)合樣式辖源,我想應(yīng)該可以滿足您的需求了,如果這些圖文結(jié)合的樣式還是無法滿足您的需求時則您還是別用UIButton了希太。
為了方便大家的使用克饶,我把上面的圖文結(jié)合樣式整理成了一個UIButton的分類方法,大家可以直接拷貝使用:

頭文件:

//  
//  UIButton+ImageTitleStyle.h  
//  
//  Created by 歐陽大哥 on 14-7-13\.  
//  QQ:156355113
//  Github:  https://github.com/youngsoft
//  Email:  obq0387_cn@sina.com
//  

#import <UIKit/UIKit.h>  

/* 
 針對同時設(shè)置了Image和Title的場景時UIButton中的圖片和文字的關(guān)系 
 */  
typedef NS_ENUM(NSInteger, ButtonImageTitleStyle ) {  
    ButtonImageTitleStyleDefault = 0,       //圖片在左誊辉,文字在右矾湃,整體居中。  
    ButtonImageTitleStyleLeft  = 0,         //圖片在左芥映,文字在右洲尊,整體居中远豺。  
    ButtonImageTitleStyleRight     = 2,     //圖片在右奈偏,文字在左,整體居中躯护。  
    ButtonImageTitleStyleTop  = 3,          //圖片在上惊来,文字在下,整體居中棺滞。  
    ButtonImageTitleStyleBottom    = 4,     //圖片在下裁蚁,文字在上,整體居中继准。  
    ButtonImageTitleStyleCenterTop = 5,     //圖片居中枉证,文字在上距離按鈕頂部。  
    ButtonImageTitleStyleCenterBottom = 6,  //圖片居中移必,文字在下距離按鈕底部室谚。  
    ButtonImageTitleStyleCenterUp = 7,      //圖片居中,文字在圖片上面崔泵。  
    ButtonImageTitleStyleCenterDown = 8,    //圖片居中秒赤,文字在圖片下面。  
    ButtonImageTitleStyleRightLeft = 9,     //圖片在右憎瘸,文字在左入篮,距離按鈕兩邊邊距
    ButtonImageTitleStyleLeftRight = 10,    //圖片在左,文字在右幌甘,距離按鈕兩邊邊距
};  

@interface UIButton (ImageTitleStyle)  

/* 
 調(diào)整按鈕的文本和image的布局潮售,前提是title和image同時存在才會調(diào)整痊项。 
 padding是調(diào)整布局時整個按鈕和圖文的間隔。 

 */  
-(void)setButtonImageTitleStyle:(ButtonImageTitleStyle)style padding:(CGFloat)padding;  

@end  

實現(xiàn)文件:

//
//  UIButton+ImageTitleStyle.m
//
//  Created by 歐陽大哥 on 14-7-13.
//

#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

上面的方法setButtonImageTitleStyle:(ButtonImageTitleStyle)style padding:(CGFloat)padding請在建立完UIButton對象并且指定一個具體的frame值或者自動布局的約束尺寸后,并且調(diào)用setTitle:forState:setImage:forSate:后再調(diào)用:

UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0,0,100,100)];
[button setTitle:@"測試文本" forState:UIControlStateNormal];
[button setImage:[UIImage imageNamed:@"test"] forState:UIControlStateNormal];
[button setButtonImageTitleStyle:ButtonImageTitleStyleTop padding:10];

另外如果你想要你的按鈕中的圖片和文字整體的水平居左肮砾,或者水平居右诀黍,或者垂直居上或者垂直居下則可以用UIButton的原生(UIControl)屬性:

@property(nonatomic) UIControlContentVerticalAlignment contentVerticalAlignment;     // how to position content vertically inside control. default is center
@property(nonatomic) UIControlContentHorizontalAlignment contentHorizontalAlignment; // how to position content hozontally inside control. default is center

這兩個屬性來設(shè)置按鈕的垂直和水平的整體位置的調(diào)整,具體設(shè)置則讀者自行去實踐吧仗处。

參考文檔:
https://segmentfault.com/a/1190000004958454

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末眯勾,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子婆誓,更是在濱河造成了極大的恐慌吃环,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件洋幻,死亡現(xiàn)場離奇詭異郁轻,居然都是意外死亡,警方通過查閱死者的電腦和手機文留,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進(jìn)店門好唯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人燥翅,你說我怎么就攤上這事骑篙。” “怎么了森书?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵靶端,是天一觀的道長。 經(jīng)常有香客問我拄氯,道長躲查,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任译柏,我火速辦了婚禮镣煮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘鄙麦。我一直安慰自己典唇,他們只是感情好镊折,可當(dāng)我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著介衔,像睡著了一般恨胚。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上炎咖,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天赃泡,我揣著相機與錄音,去河邊找鬼乘盼。 笑死升熊,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的绸栅。 我是一名探鬼主播级野,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼粹胯!你這毒婦竟也來了蓖柔?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤风纠,失蹤者是張志新(化名)和其女友劉穎况鸣,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體议忽,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡懒闷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年十减,在試婚紗的時候發(fā)現(xiàn)自己被綠了栈幸。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡帮辟,死狀恐怖速址,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情由驹,我是刑警寧澤芍锚,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站蔓榄,受9級特大地震影響并炮,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜甥郑,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一逃魄、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧澜搅,春花似錦伍俘、人聲如沸邪锌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽觅丰。三九已至,卻和暖如春妨退,著一層夾襖步出監(jiān)牢的瞬間妇萄,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工咬荷, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留嚣伐,地道東北人。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓萍丐,卻偏偏與公主長得像轩端,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子逝变,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內(nèi)容