在開發(fā)中我們經(jīng)常會用到一個圖片加文字的控件,我們首先想到的用UIButton,但是在UIButton中文字和圖片的布局默認是圖片在右文字在左邊(見下圖),而我們往往需要的并不是這樣的布局,所以大部分時候會自定義滿足我們需求的控件,或者繼承UIButton,在layoutSubviews重新布局titleLabel和imageView。但是對于這簡單控件自定義控件顯得大材小用。而UIButton中的titleEdgeInsets和imageEdgeInsets可以管理button中image和title的布局。
默認樣式
- 圖片在右,文字在左
!注:titleEdgeInsets和imageEdgeInsets是相對于原始位置的,所以默認為UIEdgeInsetsZero
// 相比較原來的位置,文字相對左邊的距離減少了圖片的寬度,右邊距離增加了圖片的的寬度
btn.titleEdgeInsets = UIEdgeInsetsMake(0, -btn.imageView.frame.size.width, 0, btn.imageView.frame.size.width);
// 相比較原來的位置,圖片距離左邊的距離增加了文字的寬度,右邊距離減少了文字的寬度
btn.imageEdgeInsets = UIEdgeInsetsMake(0, btn.titleLabel.frame.size.width, 0, -btn.titleLabel.frame.size.width);
字左圖右
問題:但是,如果你交換上面兩行代碼的位置,你會發(fā)現(xiàn)運行結(jié)果是這樣的
交換代碼后的結(jié)果
這是因為,ios8之后titleLabel的size默認為CGSizeZero,如果先設(shè)置titleEdgeInsets,titleLabel的size會被系統(tǒng)計算出來,再取就不是CGSizeZero。但如果先設(shè)置imageEdgeInsets,取出titleLabel的size為CGSizeZero,就會出現(xiàn)上圖中的問題。
解決辦法:
1、像上面代碼先設(shè)置titleEdgeInsets
2、調(diào)用titleLabel的intrinsicContentSize,代碼如下:
btn.imageEdgeInsets = UIEdgeInsetsMake(0, btn.titleLabel.intrinsicContentSize.width, 0, -btn.titleLabel.intrinsicContentSize.width);
- 文字和圖片都居中
btn.imageEdgeInsets = UIEdgeInsetsMake(0, btn.titleLabel.intrinsicContentSize.width*0.5, 0, -btn.titleLabel.intrinsicContentSize.width*0.5);
btn.titleEdgeInsets = UIEdgeInsetsMake(0, -btn.imageView.intrinsicContentSize.width*0.5, 0, btn.imageView.intrinsicContentSize.width*0.5);
// 或者(只設(shè)置一邊距離,默認會減少一半)
// btn.imageEdgeInsets = UIEdgeInsetsMake(0, btn.titleLabel.intrinsicContentSize.width, 0, 0);
// btn.titleEdgeInsets = UIEdgeInsetsMake(0, -btn.imageView.intrinsicContentSize.width, 0, 0);
居中
- 上圖片下文字
btn.imageEdgeInsets = UIEdgeInsetsMake(-btn.titleLabel.intrinsicContentSize.height*0.5, btn.titleLabel.intrinsicContentSize.width*0.5, btn.titleLabel.intrinsicContentSize.height*0.5, -btn.titleLabel.intrinsicContentSize.width*0.5);
btn.titleEdgeInsets = UIEdgeInsetsMake(btn.imageView.intrinsicContentSize.height*0.5, -btn.imageView.intrinsicContentSize.width*0.5, -btn.imageView.intrinsicContentSize.height*0.5, btn.imageView.intrinsicContentSize.width*0.5);
//或者(只設(shè)置一邊距離,默認會減少一半)
// btn.imageEdgeInsets = UIEdgeInsetsMake(-btn.titleLabel.intrinsicContentSize.height, btn.titleLabel.intrinsicContentSize.width, 0, 0);
// btn.titleEdgeInsets = UIEdgeInsetsMake(btn.imageView.intrinsicContentSize.height, -btn.imageView.intrinsicContentSize.width, 0, 0);
上圖片下文字
- 下圖片上文字
btn.imageEdgeInsets = UIEdgeInsetsMake(btn.titleLabel.intrinsicContentSize.height*0.5, btn.titleLabel.intrinsicContentSize.width*0.5, -btn.titleLabel.intrinsicContentSize.height*0.5, -btn.titleLabel.intrinsicContentSize.width*0.5);
btn.titleEdgeInsets = UIEdgeInsetsMake(-btn.imageView.intrinsicContentSize.height*0.5, -btn.imageView.intrinsicContentSize.width*0.5, btn.imageView.intrinsicContentSize.height*0.5, btn.imageView.intrinsicContentSize.width*0.5);
//或者(只設(shè)置一邊距離,默認會減少一半)
btn.imageEdgeInsets = UIEdgeInsetsMake(btn.titleLabel.intrinsicContentSize.height, btn.titleLabel.intrinsicContentSize.width, 0, 0);
btn.titleEdgeInsets = UIEdgeInsetsMake(-btn.imageView.intrinsicContentSize.height, -btn.imageView.intrinsicContentSize.width, 0, 0);
下圖片上文字
最后,我把這幾種類型寫成了一個Category,只要簡單的調(diào)用就可以了。代碼在這里。
本文雖然很簡單,卻是在開發(fā)中很實用的技巧。