UIButton自定义图片文字位置
运行如下代码:
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(40, 100, 200, 70);
// button.center = self.view.center;
[button setImage:[UIImage imageNamed:@"icon1"] forState:UIControlStateNormal];
[button setTitle:@"按钮1" forState:UIControlStateNormal];
button.backgroundColor = [UIColor grayColor];
[self.view addSubview:button];
可以看出UIButton的默认显示样式是图片居左,文字居右,如下图1:
我们操作什么属性 能够更改其设置呢?
水平方向的设置我们可以通过:UIControlContentHorizontalAlignment
typedef NS_ENUM(NSInteger, UIControlContentHorizontalAlignment) {
UIControlContentHorizontalAlignmentCenter = 0,
UIControlContentHorizontalAlignmentLeft = 1,
UIControlContentHorizontalAlignmentRight = 2,
UIControlContentHorizontalAlignmentFill = 3,
UIControlContentHorizontalAlignmentLeading API_AVAILABLE(ios(11.0), tvos(11.0)) = 4,
UIControlContentHorizontalAlignmentTrailing API_AVAILABLE(ios(11.0), tvos(11.0)) = 5,
};
button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
垂直方向的设置我们可以通过:UIControlContentVerticalAlignment
typedef NS_ENUM(NSInteger, UIControlContentVerticalAlignment) {
UIControlContentVerticalAlignmentCenter = 0,
UIControlContentVerticalAlignmentTop = 1,
UIControlContentVerticalAlignmentBottom = 2,
UIControlContentVerticalAlignmentFill = 3,
};
但是有时候我们根据需求需要调整按钮中图片和标题的位置,最常见的就是图片居上,文字居下显示的按钮,如下图所示:
实现这种居中显示的图上文下的按钮方式有很多,比如最简单的方法:自定义View,上面放一个UIButton一个UILabel子控件。
通过UIEdgeInsets调整位置
UIEdgeInsets有四个参数:top, left, bottom, right,分别代表上左下右的偏移量。
top : 为正数的时候,是往下偏移,为负数的时候往上偏移;
left : 为正数的时候往右偏移,为负数的时候往左偏移;
bottom : 为正数的时候往上偏移,为负数的时候往下偏移;
right :为正数的时候往左偏移,为负数的时候往右偏移;
@property(nonatomic) UIEdgeInsets contentEdgeInsets UI_APPEARANCE_SELECTOR; // default is UIEdgeInsetsZero. On tvOS 10 or later, default is nonzero except for custom buttons.
@property(nonatomic) UIEdgeInsets titleEdgeInsets; // default is UIEdgeInsetsZero
reverses to shift between engrave and emboss appearance
@property(nonatomic) UIEdgeInsets imageEdgeInsets;
修改图片标题的位置主要是用了UIButton的两个位置属性:
titleEdgeInsets
imageEdgeInsets
。
左文字 右图片
UIImage *image = button.imageView.image;
[button setTitleEdgeInsets:UIEdgeInsetsMake(0, -image.size.width, 0, image.size.width)];
[button setImageEdgeInsets:UIEdgeInsetsMake(0, button.titleLabel.bounds.size.width, 0, -button.titleLabel.bounds.size.width)];
在这里我们相当于把文字向左移动可一个图片都宽度,而图片向右移动了文字的宽度。在此我们还可以设置图片和文字之间的间距:
[button setTitleEdgeInsets:UIEdgeInsetsMake(0, -image.size.width - 10, 0, image.size.width)];
[button setImageEdgeInsets:UIEdgeInsetsMake(0, button.titleLabel.bounds.size.width + 10, 0, -button.titleLabel.bounds.size.width)];
上图片 下文字
[button setTitleEdgeInsets:UIEdgeInsetsMake(button.imageView.frame.size.height ,-button.imageView.frame.size.width, 0.0,0.0)];
[button setImageEdgeInsets:UIEdgeInsetsMake(-button.imageView.frame.size.height, 0.0,0.0, -button.titleLabel.bounds.size.width)];
上文字 下图片
[button setTitleEdgeInsets:UIEdgeInsetsMake(-button.imageView.frame.size.height ,-button.imageView.frame.size.width, 0,0)];
[button setImageEdgeInsets:UIEdgeInsetsMake(0, 0,-button.imageView.frame.size.height, -button.titleLabel.bounds.size.width)];
UIButton渐变色
废话不多,上代码
#import <UIKit/UIKit.h>
#import "UIButton+Extensions.h"
#import "Helper.h"
NS_ASSUME_NONNULL_BEGIN
@interface ColorButton : UIButton
/**
初始化 button (生成渐变色图片填充button背景图片)
*/
+ (instancetype)buttonWithFrame:(CGRect)frame layerColors:(NSArray *)layerColors;
@end
NS_ASSUME_NONNULL_END
#import "ColorButton.h"
@implementation ColorButton
+ (instancetype)buttonWithFrame:(CGRect)frame layerColors:(NSArray *)layerColors {
ColorButton *button = [self buttonWithType:UIButtonTypeCustom];
button.backgroundColor = [UIColor clearColor];
button.frame = frame;
button.titleLabel.font = [UIFont systemFontOfSize:30];
button.titleLabel.textColor = [UIColor whiteColor];
button.layer.cornerRadius = 20;
button.layer.masksToBounds = YES;
// 设置渐变色
NSArray *defaultPercentArray = @[@(0.18),@(1)];
if (!layerColors) {
layerColors = @[(id)UIColorRGB(0x6B8FFE),(id)UIColorRGB(0x574FF2)];
}
[button gradientButtonWithSize:CGSizeMake(button.frame.size.width, button.frame.size.height)
colorArray:layerColors
percentageArray:defaultPercentArray
gradientType:GradientFromLeftBottomToRightTop];
return button;
}
@end
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
typedef NS_ENUM(NSInteger, GradientType) {
GradientFromTopToBottom = 1, //从上到下
GradientFromLeftToRight, //从做到右
GradientFromLeftTopToRightBottom, //从上到下
GradientFromLeftBottomToRightTop //从上到下
};
@interface UIImage (Util)
/**
* 根据给定的颜色,生成渐变色的图片
* @param imageSize 要生成的图片的大小
* @param colors 渐变颜色的数组
* @param percents 渐变颜色的占比数组
* @param gradientType 渐变色的类型
*/
- (UIImage *)imageWithSize:(CGSize)imageSize
gradientColors:(NSArray *)colors
percentage:(NSArray *)percents
gradientType:(GradientType)gradientType;
@end
NS_ASSUME_NONNULL_END
#import "UIImage+Util.h"
@implementation UIImage (Util)
/**
* 根据给定的颜色,生成渐变色的图片
* @param imageSize 要生成的图片的大小
* @param colorArr 渐变颜色的数组
* @param percents 渐变颜色的占比数组
* @param gradientType 渐变色的类型
*/
- (UIImage *)imageWithSize:(CGSize)imageSize
gradientColors:(NSArray *)colors
percentage:(NSArray *)percents
gradientType:(GradientType)gradientType {
NSAssert(percents.count <= 5, @"输入颜色数量过多,如果需求数量过大,请修改locations[]数组的个数");
NSMutableArray *ar = [NSMutableArray array];
for(UIColor *c in colors) {
[ar addObject:(id)c.CGColor];
}
CGFloat locations[5];
for (int i = 0; i < percents.count; i++) {
locations[i] = [percents[i] floatValue];
}
UIGraphicsBeginImageContextWithOptions(imageSize, YES, 1);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
CGColorSpaceRef colorSpace = CGColorGetColorSpace([[colors lastObject] CGColor]);
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (CFArrayRef)ar, locations);
CGPoint start;
CGPoint end;
switch (gradientType) {
case GradientFromTopToBottom:
start = CGPointMake(imageSize.width/2, 0.0);
end = CGPointMake(imageSize.width/2, imageSize.height);
break;
case GradientFromLeftToRight:
start = CGPointMake(0.0, imageSize.height/2);
end = CGPointMake(imageSize.width, imageSize.height/2);
break;
case GradientFromLeftTopToRightBottom:
start = CGPointMake(0.0, 0.0);
end = CGPointMake(imageSize.width, imageSize.height);
break;
case GradientFromLeftBottomToRightTop:
start = CGPointMake(0.0, imageSize.height);
end = CGPointMake(imageSize.width, 0.0);
break;
default:
break;
}
CGContextDrawLinearGradient(context, gradient, start, end, kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
CGGradientRelease(gradient);
CGContextRestoreGState(context);
CGColorSpaceRelease(colorSpace);
UIGraphicsEndImageContext();
return image;
}
@end
#import <UIKit/UIKit.h>
#import "UIImage+Util.h"
#import "Helper.h"
NS_ASSUME_NONNULL_BEGIN
@interface UIButton (Extensions)
/**
* 根据给定的颜色,设置按钮的颜色
* @param btnSize 这里要求手动设置下生成图片的大小,防止coder使用第三方layout,没有设置大小
* @param clrs 渐变颜色的数组
* @param percent 渐变颜色的占比数组
* @param type 渐变色的类型
*/
- (UIButton *)gradientButtonWithSize:(CGSize)btnSize
colorArray:(nullable NSArray *)clrs
percentageArray:(nullable NSArray *)percent
gradientType:(GradientType)type;
@end
NS_ASSUME_NONNULL_END
#import "UIButton+Extensions.h"
@implementation UIButton (Extensions)
- (UIButton *)gradientButtonWithSize:(CGSize)btnSize
colorArray:(NSArray *)clrs
percentageArray:(NSArray *)percent
gradientType:(GradientType)type {
static UIImage *defaultImage = nil;
UIImage *backImage = nil;
if (!percent) {
percent = @[@(0.18),@(1)];
}
if (!clrs) {
clrs = @[(id)UIColorRGB(0x6B8FFE),(id)UIColorRGB(0x574FF2)];
if (!defaultImage) {
defaultImage = [[UIImage alloc] imageWithSize:btnSize gradientColors:clrs percentage:percent gradientType:type];
}
backImage = defaultImage;
} else {
backImage = [[UIImage alloc] imageWithSize:btnSize gradientColors:clrs percentage:percent gradientType:type];
}
[self setBackgroundImage:backImage forState:UIControlStateNormal];
return self;
}
@end
UIButton扩大按钮点击区域
按钮扩大点击区域,具体原理可查看iOS中触摸事件传递和响应原理
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface ExpandTouchButton : UIButton
/**
扩大热区范围 例如上下左右各扩大10 (-10 , -10, -10 , -10) 如果设置正值则会将按钮可点击区域缩小
*/
@property (nonatomic, assign) UIEdgeInsets expandEdgeInsets;
/**
实际可点击范围
*/
@property (nonatomic, assign, readonly) CGRect realTouchBouns;
@end
NS_ASSUME_NONNULL_END
#import "ExpandTouchButton.h"
@implementation ExpandTouchButton
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
return CGRectContainsPoint(self.realTouchBouns, point);
}
- (CGRect)realTouchBouns {
return CGRectMake(_expandEdgeInsets.left,
_expandEdgeInsets.top,
self.frame.size.width - _expandEdgeInsets.left - _expandEdgeInsets.right,
self.frame.size.height - _expandEdgeInsets.top - _expandEdgeInsets.bottom);
}
- (BOOL)isExclusiveTouch {
return YES;
}
@end
示例:
/**
* 扩大按钮点击区域
*/
- (void)test3 {
ExpandTouchButton *button = [ExpandTouchButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(100, 100, 200, 70);
// button.center = self.view.center;
[button setImage:[UIImage imageNamed:@"order_waiting_pay"] forState:UIControlStateNormal];
[button setTitle:@"我是扩大点击范围按钮" forState:UIControlStateNormal];
button.backgroundColor = [UIColor grayColor];
button.expandEdgeInsets = UIEdgeInsetsMake(-50, -50, -50, -50);
[self.view addSubview:button];
[button addTarget:self action:@selector(logtest) forControlEvents:UIControlEventTouchUpInside];
}
- (void)logtest {
NSLog(@"按钮被点击了-----------");
}