图片文字的并排布局在项目中非常的常见,iOS系统中没有很好的控件来具体的实现,虽然系统的UIButton的功能可以实现部分此类的功能,但是使用UIButton时自动布局不是太友好,需要固定button 的大小但是实际的开发中button的大小是不固定的,大小是根据图片和文字改变的,而且图片和文字的距离难以设置,通过多个控件(UIImageView ,UILabel)组合也可以实现,如果需要添加点击事件还需要在包装一层view,这种情况会造成代码的冗余,而且相应的文件代码量同样也会增多,基于以上可以封装通用的图片文字混排组件
通过自定义的图文并排,遇到此类的布局不需要过多的控件组合实现,以实现在App的通用,减少代码的量及相应功能的开发时间,使实现的效果更好,提高用户的使用体验。
效果图
具体实现
- 自定义View在此View中声明UIImageView,UILabel实现类似于系统按钮的点击方法和图文并排
- 通过枚举实现图文位置,布局的方式,点击的方式
- 声明类似于UIButton的点击方法,给自定义的View添加点击事件
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
typedef NS_ENUM(NSUInteger, TextImagePosition) {
TextImagePositionTop = 0,//图片在上面
TextImagePositionBottom = 1,//图片在下面
TextImagePositionLeft = 2,//图片在左面
TextImagePositionRight = 3,//图片在右面
};
typedef NS_ENUM(NSUInteger, TextImageLayout) {
TextImageLayoutEdgeZero = 0, // 图片或者文字到边距是零
TextImageLayoutCenter, //图片文字剧中的
};
typedef NS_ENUM(NSUInteger, TouchesEvents) {
TouchesEventsBegan = 0, //触摸开始
TouchesEventsEnd, // 触摸结束
};
@interface OCTextImageView : UIView
@property (nonatomic, strong) UIView *bgView;
@property (nonatomic, strong) UIImageView *imageView;//图片
@property (nonatomic, strong) UILabel *titleLabel;//标题
@property (nonatomic, assign) BOOL selected;//按钮的选择属性
//控制字体与控件边界的间隙,只有TextImageLayoutEdgeZero设置有效
@property (nonatomic, assign) UIEdgeInsets contentEdgeInsets;
- (instancetype)initSpace:(double)space
layoutType:(TextImageLayout)layoutType
positionType:(TextImagePosition)positionType;
- (instancetype)initText:(NSString *)text
image:(NSString *)name
font:(UIFont *)font
textColor:(UIColor *)textColor
space:(double)space
layoutType:(TextImageLayout)layoutType
positionType:(TextImagePosition)positionType;
//TargetAction回调
-(void)addTarget:(id)target
action:(SEL)action forTouchesEvents:(TouchesEvents)eventTouch;
@end
#import "OCTextImageView.h"
@interface OCTextImageView ()
@property (nonatomic,weak) id target;
@property (nonatomic, assign) SEL action;
@property (nonatomic, assign) CGRect rect;
@property (nonatomic, assign) TouchesEvents eventTouch;
@property (nonatomic, assign) TextImagePosition positionType;
@property (nonatomic, assign) TextImageLayout layoutType;
@property (nonatomic, assign) double space;
@end
@implementation OCTextImageView
- (instancetype)initSpace:(double)space
layoutType:(TextImageLayout)layoutType
positionType:(TextImagePosition)positionType {
if (self = [super init])
{
self.space = space;
self.positionType = positionType;
self.layoutType = layoutType;
[self makeSpace:space layoutType:layoutType positionType:positionType];
}
return self;
}
- (instancetype)initText:(NSString *)text
image:(NSString *)name
font:(UIFont *)font
textColor:(UIColor *)textColor
space:(double)space
layoutType:(TextImageLayout)layoutType
positionType:(TextImagePosition)positionType {
if(self = [super init])
{
self.titleLabel.text = text;
if(name.length > 0)
{
self.imageView.image = IMAGE(name);
}
self.titleLabel.textColor = textColor;
self.titleLabel.font = font;
self.space = space;
self.positionType = positionType;
self.layoutType = layoutType;
[self makeSpace:space layoutType:layoutType positionType:positionType];
}
return self;
}
/* 布局 */
- (void)makeSpace:(double)space
layoutType:(TextImageLayout)layoutType
positionType:(TextImagePosition)positionType {
[self addSubview:self.bgView];
[self.bgView addSubview:self.titleLabel];
[self.bgView addSubview:self.imageView];
if(layoutType == TextImageLayoutCenter)
{
[self.bgView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.center.equalTo(self);
}];
[self textImageLayout];
}
if(layoutType == TextImageLayoutEdgeZero)
{
[self.bgView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.top.right.bottom.equalTo(self).offset(0);
}];
[self textImageLayout];
}
}
- (void)textImageLayout {
//左
if(self.positionType == TextImagePositionLeft)
{
[self.imageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.top.bottom.equalTo(self.bgView).offset(0);
}];
[self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.top.bottom.equalTo(self.bgView).offset(0);
make.left.equalTo(self.imageView.mas_right).offset(self.space);
}];
}
//右
if(self.positionType == TextImagePositionRight)
{
[self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.top.bottom.equalTo(self.bgView).offset(0);
}];
[self.imageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.top.bottom.equalTo(self.bgView).offset(0);
make.left.equalTo(self.titleLabel.mas_right).offset(self.space);
}];
}
//上
if(self.positionType == TextImagePositionTop)
{
[self.imageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.top.right.equalTo(self.bgView).offset(0);
make.centerX.equalTo(self.bgView);
}];
[self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.imageView.mas_bottom).offset(self.space);
make.centerX.equalTo(self.bgView);
make.left.bottom.right.equalTo(self.bgView).offset(0);
}];
}
//下
if(self.positionType == TextImagePositionBottom)
{
[self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.top.right.equalTo(self.bgView).offset(0);
make.centerX.equalTo(self.bgView);
}];
[self.imageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.bottom.right.equalTo(self.bgView).offset(0);
make.centerX.equalTo(self.bgView);
make.top.equalTo(self.titleLabel.mas_bottom).offset(self.space);
}];
}
}
/* TargetAction回调 */
-(void)addTarget:(id)target action:(SEL)action forTouchesEvents:(TouchesEvents)eventTouch {
self.target = target;
self.action = action;
self.eventTouch = eventTouch;
}
/* 开始触摸 */
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
if(self.eventTouch == TouchesEventsBegan)
{
[self touches:touches withEvent:event];
}
}
/* 结束触摸 */
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
if(self.eventTouch == TouchesEventsEnd)
{
[self touches:touches withEvent:event];
}
}
- (void)touches:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
//获取触摸对象
UITouch *touche = [touches anyObject];
//获取touche的位置
CGPoint point = [touche locationInView:self];
//判断点是否在button中
if (CGRectContainsPoint(self.bounds, point))
{
//执行action
if(!self.target)
{
return;
}
else
{
NSString *methodName = NSStringFromSelector(self.action);//获取方法名字
if([methodName hasSuffix:@":"])
{//有参数
IMP imp = [self.target methodForSelector:self.action];
CGRect (*func)(id, SEL, CGRect, UIView *) = (void *)imp;
self.rect = self.target?
func(self.target, self.action, self.rect, self) : CGRectZero;
}
else
{//没有
IMP imp = [self.target methodForSelector:self.action];
void (*func)(id, SEL) = (void *)imp;
func(self.target, self.action);
}
}
}
}
- (void)setContentEdgeInsets:(UIEdgeInsets)contentEdgeInsets {
if(self.layoutType == TextImageLayoutEdgeZero)
{
_contentEdgeInsets = contentEdgeInsets;
[self.bgView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.edges.mas_equalTo(contentEdgeInsets);
}];
}
}
#pragma mark -- lazy
- (UIView *)bgView {
if(_bgView == nil)
{
_bgView = [[UIView alloc] init];
}
return _bgView;
}
- (UIImageView *)imageView {
if (_imageView == nil)
{
_imageView = [[UIImageView alloc] init];
_imageView.contentMode = UIViewContentModeScaleAspectFit;
}
return _imageView;
}
- (UILabel *)titleLabel {
if (_titleLabel == nil)
{
_titleLabel = [[UILabel alloc] init];
_titleLabel.textAlignment = NSTextAlignmentCenter;
}
return _titleLabel;
}
@end