iOS常用到有標題同時有圖片的按鈕蟹演,但是系統(tǒng)控件默認只提供圖片在左阴颖,標題在右的樣式,想要其他的樣式就需要自己處理云头,常用的處理方式有兩種捐友。
一種是設置兩個UIEdgeInsets屬性
@property(nonatomic) UIEdgeInsets titleEdgeInsets;
@property(nonatomic) UIEdgeInsets imageEdgeInsets;
相信用過這兩個設置的都知道,按鈕用這兩個設置很難找準位置溃槐。
另外一種是兩個接口
- (CGRect)titleRectForContentRect:(CGRect)contentRect;
- (CGRect)imageRectForContentRect:(CGRect)contentRect;
兩個接口可以分別設置圖片和標題的位置匣砖。效果圖
圖片在右.png
圖片在左.png
圖片在上.png
圖片在下.png
為了方便使用一般都會封裝一個UIButton的子類,寫一個結構體作為圖片和標題相對位置的設置選擇和內部處理判斷。
typedef enum {
imageTop = 0, // 圖片上 標題下
imageLeft, // 圖片左 標題右
imageBottom, // 圖片下 標題上
imageRight, // 圖片右 標題左
} ImageStyle;
- (CGRect)imageRectForContentRect:(CGRect)contentRect{
if (self.buttonStyle == imageRight) {
return [self imageRectWithImageRightForContentTect:contentRect];
}
else if (self.buttonStyle == imageTop){
return [self imageRectWithImageTopForContentTect:contentRect];
}
else if (self.buttonStyle == imageBottom){
return [self imageRectWithImageBottomForContentTect:contentRect];
}
else {
return [self imageRectWithImageLeftForContentTect:contentRect];
}
}
- (CGRect)titleRectForContentRect:(CGRect)contentRect{
if (self.buttonStyle == imageRight) {
return [self titleRectWithImageRightForContentTect:contentRect];
}
else if (self.buttonStyle == imageTop){
return [self titleRectWithImageTopForContentTect:contentRect];
}
else if (self.buttonStyle == imageBottom){
return [self titleRectWithImageBottomForContentTect:contentRect];
}
else {
return [self titleRectWithImageLeftForContentTect:contentRect];
}
}
初始化方法中做一些默認設置,設置font是因為在處理方法中用于判斷標題的長度或者寬度猴鲫,按說系統(tǒng)一定有默認值的砌溺,但是不設置就是獲取不到,所以這里做了默認的設置变隔。
- (instancetype)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
self.titleLabel.font = titleFont;
self.buttonStyle = imageLeft;
self.titleLabel.textAlignment = NSTextAlignmentCenter;
}
return self;
}
- (instancetype)init{
self = [super init];
if (self) {
self.titleLabel.font = titleFont;
self.buttonStyle = imageLeft;
self.titleLabel.textAlignment = NSTextAlignmentCenter;
}
return self;
}
常用情況下按鈕都不會占滿按鈕高度或者寬度规伐,而且多為正方形,所以在處理的時候左右布局時給圖片的尺寸定位按鈕高度的0.6匣缘,上下布局時為按鈕1/2高度的0.6猖闪。具體到有特殊需求的時候都可以調整。貼出圖片在右和圖片在上的兩個處理代碼肌厨。
#pragma mark imageRight 圖片在右 文字在左
- (CGRect)imageRectWithImageRightForContentTect:(CGRect)contentRect{
CGFloat imageWH = CGRectGetHeight(contentRect)*scale;
CGFloat inteval = (CGRectGetHeight(contentRect)-imageWH)/2;
CGFloat titleW = [self widthForTitleString:[self titleForState:UIControlStateNormal] ContentRect:contentRect];
CGFloat titleX = (CGRectGetWidth(contentRect)-titleW-imageWH)/2;
if (titleX < 0) {
titleX = 0;
}
CGRect rect = CGRectMake(titleX+titleW , inteval, imageWH, imageWH);
return rect;
}
- (CGRect)titleRectWithImageRightForContentTect:(CGRect)contentRect{
CGFloat imageWH = CGRectGetHeight(contentRect)*scale;
CGFloat titleW = [self widthForTitleString:[self titleForState:UIControlStateNormal] ContentRect:contentRect];
CGFloat titleX = (CGRectGetWidth(contentRect)-titleW-imageWH)/2;
if (titleX < 0) {
titleX = 0;
}
CGRect rect = CGRectMake(titleX, 0, titleW , CGRectGetHeight(contentRect));
return rect;
}
#pragma mark imageTop 圖片在上 文字在下
- (CGRect)imageRectWithImageTopForContentTect:(CGRect)contentRect{
CGFloat imageWH = CGRectGetHeight(contentRect)/2*scale;
CGFloat titleH = [self heightForTitleString:[self titleForState:UIControlStateNormal] ContentRect:contentRect];
CGFloat imageY = (CGRectGetHeight(contentRect)-imageWH-titleH)/2;
CGFloat imageX = (CGRectGetWidth(contentRect) - imageWH)/2;
CGRect rect = CGRectMake(imageX, imageY, imageWH, imageWH);
return rect;
}
- (CGRect)titleRectWithImageTopForContentTect:(CGRect)contentRect{
CGFloat imageWH = CGRectGetHeight(contentRect)/2*scale;
CGFloat titleH = [self heightForTitleString:[self titleForState:UIControlStateNormal] ContentRect:contentRect];
CGFloat titleY = (CGRectGetHeight(contentRect)-imageWH-titleH)/2+imageWH;;
CGRect rect = CGRectMake(0, titleY, CGRectGetWidth(contentRect) , titleH);
return rect;
}
#pragma mark 計算標題內容寬度
- (CGFloat)widthForTitleString:(NSString *)string ContentRect:(CGRect)contentRect{
if (string) {
CGSize constraint = contentRect.size;
NSAttributedString* attributedText = [[NSAttributedString alloc] initWithString:string attributes:@{NSFontAttributeName: self.titleLabel.font}];
CGRect rect = [attributedText boundingRectWithSize:constraint options:NSStringDrawingUsesLineFragmentOrigin context:nil];
CGSize size = rect.size;
CGFloat width = MAX(size.width, 30);
CGFloat imageW = [self imageForState:UIControlStateNormal].size.width;
if (width+imageW > CGRectGetWidth(contentRect)) { // 當標題和圖片寬度超過按鈕寬度時不能越界
return CGRectGetWidth(contentRect) - imageW;
}
return width+10;
}
else {
return CGRectGetWidth(contentRect)/2;
}
}
#pragma mark 計算標題文字內容的高度
- (CGFloat)heightForTitleString:(NSString *)string ContentRect:(CGRect)contentRect{
if (string) {
CGSize constraint = contentRect.size;
NSAttributedString* attributedText = [[NSAttributedString alloc] initWithString:string attributes:@{NSFontAttributeName: self.titleLabel.font}];
CGRect rect = [attributedText boundingRectWithSize:constraint options:NSStringDrawingUsesLineFragmentOrigin context:nil];
CGSize size = rect.size;
CGFloat height = MAX(size.height, 5);
if (height > CGRectGetHeight(contentRect)/2) { // 當標題高度超過按鈕1/2寬度時
return CGRectGetHeight(contentRect)/2 ;
}
return height;
}
else {
return CGRectGetHeight(contentRect)/2;
}
}
如此培慌,初始化的時候只需要設置下按鈕樣式即可,默認是圖片在左柑爸。
MCButton *button = [[MCButton alloc] initWithFrame:CGRectMake(50, 50, 100, 50)];
button.buttonStyle = imageBottom;
button.titleLabel.font = [UIFont systemFontOfSize:15.0];
[button setTitle:@"測試按鈕" forState:UIControlStateNormal];
[button setBackgroundColor:[UIColor lightGrayColor]];
[button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[button setImage:[UIImage imageNamed:@"點評_icon_評論"] forState:UIControlStateNormal];
[self.view addSubview:button];
demo地址 GitHub給個Star噢!
喜歡就點個贊唄!
歡迎大家提出更好的改進意見和建議吵护,一起進步!