iOS中UIButton實現各種圖文結合的效果以及原理

iOS的UIButton是一個非常常見而且常用的控件,我們一般用他來實現某個功能的提交以及選擇操作。我們可以建立只有文字的Button,也可以建立只有圖片的Button,具體的需求要看界面設計的具體情況。有時候我們希望應用的界面元素是豐富多彩的,有時候希望建立一個圖文結合的控件來響應用戶的手勢操作,因此建立一個即有圖片也有文字的按鈕來實現功能,這個只需要分別調用UIButton的setTitle:forState:setImage:forSate:兩個方法就可以實現具有圖片和文字功能的按鈕

但是系統默認的圖文結合的按鈕布局是:圖片在左邊而文字在右邊,而且整體水平和垂直居中
比如下面這個圖文按鈕:

系統默認的圖文結合的按鈕布局

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

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

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

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

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

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

這兩個屬性是分別用來調整按鈕中文本的偏移縮進以及圖片的偏移縮進的,他們都是一個UIEdgeInsets 對象默認的值都是0

也就是默認的值都是0的情況下按鈕的圖片和文字垂直居中,而且圖片在左邊文字在右邊,而且圖片文本整體水平居中

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

在調整之前我們先定義幾個特定的變量值:

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的值調整文本和圖片的位置。如果我們想往右移動20的話,那么就應該同時設置 UIEdgeInsets 的 left = 20, right = -20 ,而如果我們想 往上移動20 的話,那么就應該應該同時設置 UIEdgeInsets 的 top = -20 ,bottom = 20。下面我們就分別通過調整按鈕的titleEdgeInsetsimageEdgeInsets的值來實現各種圖文結合的效果:

一、圖片在左,文字在右,整體居中,調整間距

圖片在左,文字在右,整體居中,調整間距

這種方式是按鈕默認的圖文布局方式,因為要調整圖片和文本的間距,所以只需要 文本右移 padding/2.0 ,而 圖片左移 padding/2.0 值就可以了。設置的代碼為:

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

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

二、圖片在右,文字在左,整體居中

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

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

//上、左、下、右
 //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));

三、圖片在上,文字在下,整體居中

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

這種布局下當 圖片和文字要求垂直居中 后:

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

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

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

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

  • 而新的文本的水平中心點也是 selfWidth/2.0,而原來的文本的水平中心點是titleRect.origin.x + titleRect.size.width/2.0, 兩者相減就是水平需要偏移的值,又因為默認的情況下當按鈕比較小時會自動保留圖片的尺寸和將文字部分縮小,因此當我們實現文字和圖片上下布局時,需要將文字的區域擴展到整個按鈕部分,否則將會縮小按鈕的文字的寬度,因此按鈕的寬度為selfWidth, 而文字的默認寬度是titleRect.size.width,所以上面的實現將文本移到中間后還需要分別向兩邊進行拉伸(selfWidth - titleRect.size.width)/2.0來保證文本填充滿所有的按鈕區域 ,在下面的各種樣式中凡是文字和圖片垂直居中的情況下都要考慮這種情況 設置的代碼為:
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);



四、圖片在下,文字在上,整體居中

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

這種布局就是上面的文字和圖片位置調換,因此設置代碼為:


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

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

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

這種方式要求圖片在按鈕中居中,而文字則要求左右居中而垂直方向位置則是距離按鈕頂部的間隔值。 上面因為描述了水平居中的調整,因此這里就不介紹了,只介紹垂直方向的調整。 因為要求圖片要垂直居中,因此不需要調整垂直偏移。而文本則要調整為距離頂部的間隔值,也就是新的文本的頂部值等于padding, 而原來頂部值是titleRect.origin.y,因此只需要偏移titleRect.origin.y - padding就可以了。設置代碼為:

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

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

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

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

  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, 因此兩者的差值就是文字需要垂直偏移的值。代碼設置為:


  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,因此兩者的差值就是文字需要垂直偏移的值。代碼設置為:


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

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

圖片在右,文字在左,距離按鈕兩邊邊距

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

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

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

圖片在左,文字在右,距離按鈕兩邊邊距

這種方式中,圖片和文字的垂直位置不需要調整,而只需要將圖文的水平位置調整即可,而調整的方法和上面的相似,只是圖片移到左邊兒文字移到右邊而已。代碼設置為:

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

前面說的的十種圖文結合樣式,我想應該可以滿足您的需求了,如果這些圖文結合的樣式還是無法滿足您的需求時則您還是別用UIButton了。
為了方便大家的使用,我把上面的圖文結合樣式整理成了一個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>  

/* 
 針對同時設置了Image和Title的場景時UIButton中的圖片和文字的關系 
 */  
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)  

/* 
 調整按鈕的文本和image的布局,前提是title和image同時存在才會調整。 
 padding是調整布局時整個按鈕和圖文的間隔。 

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

@end  

實現文件:

//
//  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值或者自動布局的約束尺寸后,并且調用setTitle:forState:setImage:forSate:后再調用:

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

這兩個屬性來設置按鈕的垂直和水平的整體位置的調整,具體設置則讀者自行去實踐吧。

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

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,443評論 6 532
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,530評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,407評論 0 375
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,981評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,759評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,204評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,263評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,415評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,955評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,782評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,983評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,528評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,222評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,650評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,892評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,675評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,967評論 2 374

推薦閱讀更多精彩內容