UIButton的titleEdgeInsets屬性和imageEdgeInsets屬性實現圖片文字按要求排列


button可以設置 titleEdgeInsets屬性和 imageEdgeInsets屬性來調整其image和label相對位置,具體參考 http://stackoverflow.com/questions/4564621/aligning-text-and-image-on-uibutton-with-imageedgeinsets-and-titleedgeinsets/5358259#5358259的第二個答案,關鍵是這個:
 
這里說說我自己的理解,理解有誤的地方,大家可以討論
 
前提:這是在button的frame足夠顯示image和label內容的情況下,如果frame不夠,圖片或者文字會被壓縮( demo的button是xib上畫的,所以大小剛剛好
2016.4.1更新:在xib或者storyboard上畫的button,如果勾選了autolayout而不設置任何約束的話,系統會自動給button加上約束,
而且加上的約束是根據其在xib上的frame加的,這個約束會導致你重新設置title或者image button的大小也不會變;
所以建議還是提前設置好約束,對於button或者label來說,因為有intrinsicSize的存在,所以可以不設置寬高,只設置相對於其他空間的位置)
 
前置知識點:titleEdgeInsets是title相對於其上下左右的inset,跟tableView的contentInset是類似的,
如果只有title,那它上下左右都是相對於button的,image也是一樣;
如果同時有image和label,那這時候image的上左下是相對於button,右邊是相對於label的;title的上右下是相對於button,左邊是相對於image的。
 
我寫了個demo來說明怎么設置這兩個屬性以達到自己想要的效果: https://github.com/Phelthas/Demo_ButtonImageTitleEdgeInsets
看效果圖來說明一下:
其中,右邊的是給對應的左邊的button及button.imageView, button.titleLabel加上邊框的效果
 
默認情況下,button的image和label是緊貼着居中的,
那如果想要image在右邊,label在左邊應該怎么辦呢?
答案就是:
self.oneButton.imageEdgeInsets = UIEdgeInsetsMake(0, labelWidth, 0, -labelWidth);
self.oneButton.titleEdgeInsets = UIEdgeInsetsMake(0, -imageWith, 0, imageWith);
來解釋一下為什么:
其實就是這一句:This property is used only for positioning the image during layout
其實titleEdgeInsets屬性和 imageEdgeInsets屬性只是在畫這個button出來的時候用來調整image和label位置的屬性,並不影響button本身的大小(這個看第三排的圖比較明顯),
它們只是image和button相較於原來位置的偏移量,那什么是原來的位置呢?就是 這個沒有設置edgeInset時候的位置了。
 
如要要image在右邊,label在左邊,那image的左邊相對於button的左邊右移了labelWidth的距離,image的右邊相對於label的左邊右移了labelWidth的距離
所以,self.oneButton.imageEdgeInsets = UIEdgeInsetsMake(0, labelWidth, 0, -labelWidth);為什么是負值呢?因為這是contentInset,是偏移量,不是距離
同樣的,label的右邊相對於button的右邊左移了imageWith的距離,label的左邊相對於image的右邊左移了imageWith的距離
所以self.oneButton.titleEdgeInsets = UIEdgeInsetsMake(0, -imageWith, 0, imageWith);
這樣就完成image在右邊,label在左邊的效果了。
 
 
第三排,image在上,label在下
同樣的第三排調整前的還是第一排的樣子,
跟第一排比起來,image的中心位置向右移動了 CGFloat imageOffsetX = (imageWith + labelWidth) / 2 - imageWith / 2;
上向上移動了 CGFloat imageOffsetY = imageHeight / 2;
所以self.twoButton.imageEdgeInsets = UIEdgeInsetsMake(-imageOffsetY, imageOffsetX, imageOffsetY, -imageOffsetX);
label的中心位置像左移動了CGFloat labelOffsetX = (imageWith + labelWidth / 2) - (imageWith + labelWidth) / 2;
向下移動了CGFloat labelOffsetY = labelHeight / 2;
所以self.twoButton.titleEdgeInsets = UIEdgeInsetsMake(labelOffsetY, -labelOffsetX, -labelOffsetY, labelOffsetX);
然后就大功告成了,現在已經完美實現一個button內image在上,label在下,且居中了
 
2016.4.1更新
根據stackoverflow 上的解釋,加入contentInset的考慮,可以很好的解決intrinsicSize的問題,效果如圖:
其中約束是:
左邊一列左對齊,上下間隔25
中間一列居中對齊,上下間隔25
右邊一列右對齊,上下間隔25
全部不設置寬高,用button的intrinsicSize來確定大小
 
左邊一列和中間一列是只設置了titleEdgeInsets屬性和imageEdgeInsets的效果;
右邊一列是追加了contentInset的效果;
 
button的可主控范圍是綠色框框內的部分,在模擬器上可以試試,點擊不在綠色框框內的部分button是不會有響應的。
為什么呢?還是文章最上面的那句,titleEdgeInsets屬性和imageEdgeInsets只是用來設置title和image的位置,但是系統不會用它們來計算button的intrinsicSize;
button是用contentInset來計算其intrinsicSize的大小的!!!
所以右邊一列是更好的,可以比完美的配合autoLayout;
 
另:這個用button自身屬性來實現圖片文字自由排列的方法已經封裝成一個分類,而且已經支持cocoaPods了
只需要一行代碼,就可以實現右邊一列的效果:
[self.twoButton_line setImagePosition:LXMImagePositionTop spacing:10];
歡迎使用~~ 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM