轉:http://www.cnblogs.com/huichun/p/3419596.htmlhtml
uiButton控件上自帶了一個uiLabel類型的子控件和一個uiImageView類型的子控件,若是能夠正確使用他們的edgeInsets屬性,就能把button設置成咱們想要的樣子。app
關於titleEdgeInsets,蘋果文檔的解釋是:The inset or outset margins for the rectangle around the button’s title text,並且imageEdgeInsets也是相似,都沒有講怎麼設。事實上,這兩個東西是有聯繫的,經常會形成困惑:我只設了其中一個的edgeInsets,爲何button上的圖片和文字佈局都變了?佈局
這裏是一個同事花一個下午的時間,專門寫一段button的代碼,分析數據,總結出來的小規律,並不權威,可是挺好用的,總結出來分享一下。測試
默認狀況下,imageEdgeInsets和titleEdgeInsets都是0。先不考慮height,ui
if (button.width小於imageView上image的width){圖像會被壓縮,文字不顯示}orm
if (button.width < imageView.width + label.width){圖像正常顯示,文字顯示不全}htm
if (button.width >= imageView.width + label.width){圖像和文字都居中顯示,imageView在左,label在右,中間沒有空隙} blog
實際app應用中,一般會已知以下參數,佈局button圖片
button的width:BUTTON_WIDTH文檔
button上控件imageView的的圖片爲image
label上的文字爲:@「這是一個測試」
爲了避免看着頭疼,不寫那麼多的常量了,以具體的數字來舉例吧,咱們想讓imageView在前,label在後,居中顯示,imageView在button上離左邊界至少爲距離10,label離button右邊界爲距離爲至少爲10,imageView和label之間的距離爲5,代碼能夠以下寫:
NSString *title = @"這是一個測試";
[button setTitle:title forState:UIControlStateNormal];
[button setImage:image forState:UIControlStateNormal];
CGSize strSize = [title sizeWithFont:button.titleLabel.font];
CGFloat totalLen = strSize.width + 5 + image.size.width;
CGFloat edgeLen = (TAGS_BUTTON_WIDTH - totalLen) / 2;
if (edgeLen < 10) {
edgeLen = 10;
}
[button setImageEdgeInsets:UIEdgeInsetsMake(0, edgeLen, 0, edgeLen + 5)];
[button setTitleEdgeInsets:UIEdgeInsetsMake(0, edgeLen + 5, 0, edgeLen)];
設置edgeInsets要始終記住的一個原則是:將label和imageView當作一個總體,imageView在前,label在後,中間沒有空隙。。這段代碼中,設置imageEdgeInsets時,imageView與左邊距離爲計算好的edgeLen,右邊距是按照button的默認佈局,label的右邊與button右邊的距離,就是label實際的右邊應當與button右邊的距離再向左移動5(實際中imageView與label有間距5,默認佈局下可沒有這個5,得把這個5讓出來),就是edgeLen + 5。設置titleEdgeInset時,label與右邊爲計算好的edgeLen,想象imageView還在label的左邊,與label沒有空隙的話,那這個總體與左邊的距離應該是多少呢?就是edgeLen+5,把間隙的5讓出來嘛。
咱們再想一個稍複雜的狀況:若是label在左,imageView在右,imageView在button上離右邊界爲固定值10,label離button左邊界也爲固定值10,應該怎麼設呢?能夠以下寫代碼:
NSString *title = @"這是一個測試";
[button setTitle:title forState:UIControlStateNormal];
[button setImage:image forState:UIControlStateNormal];
CGSize strSize = [title sizeWithFont:button.titleLabel.font];
[button setImageEdgeInsets:UIEdgeInsetsMake(0, BUTTON_WIDTH - 10 - image.size.width, 0, (10 - strSize.width))];
CGFloat titleRightInset = BUTTON_WIDTH - 10 - strSize.width;
if (titleRightInset < 10 + image.size.width) {
titleRightInset = 10 + image.size.width;
}
[button setTitleEdgeInsets:UIEdgeInsetsMake(0, (10 - image.size.width), 0, titleRightInset)];
解釋這段代碼以前再強調一下UIButton控件的默認佈局:imageView在左,label在右,中間沒有空隙。imageView的左側與button的左邊界距離爲button的width,去掉右側留出的10,再去掉imageView的width,想像imageView後面還接着有一個label,那麼label的右側與button的右邊界距離爲10 - strSize.width,因此button的imageEdgeInsets屬性就如上面代碼的設置值了。再看label,它的右側與button右邊界的距離爲button的width,去掉左側留出的10,再去掉label的width,爲保證label後面能放下一個圖片,圖片後面還有10的空白,故對titleRightInset作了如上的一些調整。想象label的左側還有一個imageView,那麼這個總體離button左邊界的距離爲10 - image.size.width。
以上只考慮了width方向,height方向與width是獨立的,比width更容易一些。
設button的height:BUTTON_HEIGHT,若是imageView在上,與button上邊界距離爲10,label在下,與button下邊界距離爲10,可寫以下代碼。
NSString *title = @"這是一個測試";
[button setTitle:title forState:UIControlStateNormal];
[button setImage:image forState:UIControlStateNormal];
[button setImageEdgeInsets:UIEdgeInsetsMake(10, 0, BUTTON_HEIGHT - 10 - image.size.height , 0)];
[button setTitleEdgeInsets:UIEdgeInsetsMake(BUTTON_HEIGHT - 10 - button.titleLabel.frame.size.height, 0, 10, 0)];
能夠看到height方向上,imageView與label獨立變化,不用考慮彼此。