UIButton文字靠左、上、下的多种实现方式
2018-04-24 本文已影响451人
SmallWhiteMouse
写在前面:
本文主要是针对iOS系统控件UIButton进行操作,介绍多种改变图片、文本的位置关系的方式方法。提供多种做法,是希望在遇到新课题时可以为各位朋友激发一丝丝灵感。不评优劣,方式自取。
效果图:

1.继承自UIButton,重写- layoutSubveiws
////示例:实现图片上文字下.(效果图右上)
- (void)layoutSubviews{
[super layoutSubviews];
CGFloat buttonW = self.bounds.size.width;
CGFloat buttonH = self.bounds.size.height;
CGFloat imageH =buttonW - 10;
self.imageView.frame = CGRectMake(0, 0, buttonW, imageH);
self.titleLabel.frame = CGRectMake(0, imageH, buttonW, buttonH - imageH);
}
- titleLable和 imageView本来就是button的子控件,button当然有资格在这儿重新布局他的子控件。
- 当然在这儿同样可以用
NSLayoutConstraint
。
2.继承自UIButton,重写两个方法titleRectForContentRect
和imageRectForContentRect
//示例:实现图片上文字下.(效果图右上)
- (CGRect)titleRectForContentRect:(CGRect)contentRect{
CGFloat titleY = contentRect.size.height * 0.6;
CGFloat titleW = contentRect.size.width;
CGFloat titleH = contentRect.size.height * 0.4;
return CGRectMake(0, titleY, titleW, titleH);
}
- (CGRect)imageRectForContentRect:(CGRect)contentRect{
CGFloat imageW = CGRectGetWidth(contentRect);
CGFloat imageH = contentRect.size.height * 0.6;
return CGRectMake(0, 0, imageW, imageH);
}
-
返回的就是titleLabel/imageView的新位置。
-
contentRect 是切掉button内边距能显示内容的rect(很多网站帖子这儿给读者误导)
-
注意:返回值不要超过contentRect的范围;
-
这两个方法不是只调用一次,会被多次调用,只要button的title改变,都会调用此方法,最后一次调用,返回的frame值,才是最终的布局frame,所以,在这里,可以通过获取button的标题,动态地修改其frame,使title和image显示紧凑;
3、实例化UIButton并加到父控件之后修改imageView和titleLabel的内边距
//示例:实现文字左图片右.(效果图左下)
- (void)xbs_updateImageAlignmentToRightWithSpace:(CGFloat)space{
CGFloat halfSpace = space / 2.0f;
CGFloat imageWidth = self.currentImage.size.width;
[self setTitleEdgeInsets:UIEdgeInsetsMake(0, -imageWidth-halfSpace, 0, imageWidth+halfSpace)];
CGFloat edgeWidth = [self.currentTitle sizeWithAttributes:@{NSFontAttributeName:self.titleLabel.font}].width;
[self setImageEdgeInsets:UIEdgeInsetsMake(0, edgeWidth+halfSpace, 0, -edgeWidth-halfSpace)];
}
-
UIButton默认是左图片,右文字。并且在设置edge insets之前,位置已经有了设定。所以设置title的edge insets,真实的作用是在原来的边距值基础上增加或减少某个间距,负值便是减少。以title为例,设置右边距增加图片宽度,就使得自己的右边界距离按钮的右边界多了图片的宽度,正好放下图片。此时,title lable变小了,而title lable的左边界还在原来的位置上,所以lable的左边界距离按钮的左边界减少图片的宽度,lable就和原来一样大了,而且左侧起始位置和图片的左侧起始位置相同了
-
针对此方法,笔者写了一个UIButton的category:UIButton+XBSImageAlignment,里面的类目可直接拿来使用,简单调用一个方法即可;
-
如果你怕下载到病毒,请到附录copy代码。
注意:
确保你在使用UIButton+XBSImageAlignment
这个分类之前的文本和图片是可以正常显示的。
附录
- UIButton+XBSImageAlignment.h
#import <UIKit/UIKit.h>
@interface UIButton (XBSImageAlignment)
//to Right
- (void)xbs_updateImageAlignmentToRight;
//to UP
- (void)xbs_updateImageAlignmentToUp;
//to Down
- (void)xbs_updateImageAlignmentToDown;
//space : space between textLabel and imageView
- (void)xbs_updateImageAlignmentToRightWithSpace:(CGFloat)space;
- (void)xbs_updateImageAlignmentToUpWithSpace:(CGFloat)space;
- (void)xbs_updateImageAlignmentToDownWithSpace:(CGFloat)space;
@end
- //UIButton+XBSImageAlignment.m
#import "UIButton+XBSImageAlignment.h"
@implementation UIButton (XBSImageAlignment)
- (void)xbs_updateImageAlignmentToRight{
[self xbs_updateImageAlignmentToRightWithSpace:0];
}
- (void)xbs_updateImageAlignmentToRightWithSpace:(CGFloat)space{
CGFloat halfSpace = space / 2.0f;
CGFloat imageWidth = self.currentImage.size.width;
[self setTitleEdgeInsets:UIEdgeInsetsMake(0, -imageWidth-halfSpace, 0, imageWidth+halfSpace)];
CGFloat edgeWidth = [self.currentTitle sizeWithAttributes:@{NSFontAttributeName:self.titleLabel.font}].width;
[self setImageEdgeInsets:UIEdgeInsetsMake(0, edgeWidth+halfSpace, 0, -edgeWidth-halfSpace)];
}
- (void)xbs_updateImageAlignmentToUp{
[self xbs_updateImageAlignmentToUpWithSpace:0];
}
- (void)xbs_updateImageAlignmentToUpWithSpace:(CGFloat)space {
CGFloat halfSpace = space / 2.0f;
CGFloat imageWidth = self.currentImage.size.width;
CGFloat imageHeight = self.currentImage.size.height;
[self setTitleEdgeInsets:UIEdgeInsetsMake(imageHeight/2 + halfSpace, -imageWidth/2, -imageHeight/2 - halfSpace, imageWidth/2)];
CGFloat edgeWidth = [self.currentTitle sizeWithAttributes:@{NSFontAttributeName:self.titleLabel.font}].width;
CGFloat edgeHeight = [self.currentTitle sizeWithAttributes:@{NSFontAttributeName:self.titleLabel.font}].height;
[self setImageEdgeInsets:UIEdgeInsetsMake(-edgeHeight/2 - halfSpace, edgeWidth / 2, edgeHeight/2 + halfSpace, -edgeWidth/2)];
}
- (void)xbs_updateImageAlignmentToDown{
[self xbs_updateImageAlignmentToDownWithSpace:0];
}
- (void)xbs_updateImageAlignmentToDownWithSpace:(CGFloat)space {
CGFloat halfSpace = space / 2.0f;
CGFloat imageWidth = self.currentImage.size.width;
CGFloat imageHeight = self.currentImage.size.height;
[self setTitleEdgeInsets:UIEdgeInsetsMake(-imageHeight/2 - halfSpace, -imageWidth/2, imageHeight/2 + halfSpace, imageWidth/2)];
CGFloat edgeWidth = [self.currentTitle sizeWithAttributes:@{NSFontAttributeName:self.titleLabel.font}].width;
CGFloat edgeHeight = [self.currentTitle sizeWithAttributes:@{NSFontAttributeName:self.titleLabel.font}].height;
[self setImageEdgeInsets:UIEdgeInsetsMake(edgeHeight/2 + halfSpace, edgeWidth / 2, -edgeHeight/2 - halfSpace, -edgeWidth/2)];
}
@end