圖片文字的并排布局在項目中非常的常見,iOS系統中沒有很好的控件來具體的實現,雖然系統的UIButton的功能可以實現部分此類的功能,但是使用UIButton時自動布局不是太友好,需要固定button 的大小但是實際的開發中button的大小是不固定的,大小是根據圖片和文字改變的,而且圖片和文字的距離難以設置,通過多個控件(UIImageView ,UILabel)組合也可以實現,如果需要添加點擊事件還需要在包裝一層view,這種情況會造成代碼的冗余,而且相應的文件代碼量同樣也會增多,基于以上可以封裝通用的圖片文字混排組件
通過自定義的圖文并排,遇到此類的布局不需要過多的控件組合實現,以實現在App的通用,減少代碼的量及相應功能的開發時間,使實現的效果更好,提高用戶的使用體驗。
效果圖
截屏2023-05-17 09.27.28.png
具體實現
- 自定義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