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的默認(rèn)顯示樣式是圖片居左腿宰,文字居右扁藕,如下圖1:
我們操作什么屬性 能夠更改其設(shè)置呢长豁?
水平方向的設(shè)置我們可以通過: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;
垂直方向的設(shè)置我們可以通過:UIControlContentVerticalAlignment
typedef NS_ENUM(NSInteger, UIControlContentVerticalAlignment) {
UIControlContentVerticalAlignmentCenter = 0,
UIControlContentVerticalAlignmentTop = 1,
UIControlContentVerticalAlignmentBottom = 2,
UIControlContentVerticalAlignmentFill = 3,
};
但是有時候我們根據(jù)需求需要調(diào)整按鈕中圖片和標(biāo)題的位置槽华,最常見的就是圖片居上壹蔓,文字居下顯示的按鈕,如下圖所示:
實現(xiàn)這種居中顯示的圖上文下的按鈕方式有很多猫态,比如最簡單的方法:自定義View佣蓉,上面放一個UIButton一個UILabel子控件。
通過UIEdgeInsets調(diào)整位置
UIEdgeInsets有四個參數(shù):top, left, bottom, right亲雪,分別代表上左下右的偏移量勇凭。
top : 為正數(shù)的時候,是往下偏移,為負(fù)數(shù)的時候往上偏移;
left : 為正數(shù)的時候往右偏移,為負(fù)數(shù)的時候往左偏移;
bottom : 為正數(shù)的時候往上偏移,為負(fù)數(shù)的時候往下偏移;
right :為正數(shù)的時候往左偏移,為負(fù)數(shù)的時候往右偏移;
@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;
修改圖片標(biāo)題的位置主要是用了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)];
在這里我們相當(dāng)于把文字向左移動可一個圖片都寬度义辕,而圖片向右移動了文字的寬度虾标。在此我們還可以設(shè)置圖片和文字之間的間距:
[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;
// 設(shè)置漸變色
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)
/**
* 根據(jù)給定的顏色终息,生成漸變色的圖片
* @param imageSize 要生成的圖片的大小
* @param colors 漸變顏色的數(shù)組
* @param percents 漸變顏色的占比數(shù)組
* @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)
/**
* 根據(jù)給定的顏色夺巩,生成漸變色的圖片
* @param imageSize 要生成的圖片的大小
* @param colorArr 漸變顏色的數(shù)組
* @param percents 漸變顏色的占比數(shù)組
* @param gradientType 漸變色的類型
*/
- (UIImage *)imageWithSize:(CGSize)imageSize
gradientColors:(NSArray *)colors
percentage:(NSArray *)percents
gradientType:(GradientType)gradientType {
NSAssert(percents.count <= 5, @"輸入顏色數(shù)量過多,如果需求數(shù)量過大周崭,請修改locations[]數(shù)組的個數(shù)");
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)
/**
* 根據(jù)給定的顏色柳譬,設(shè)置按鈕的顏色
* @param btnSize 這里要求手動設(shè)置下生成圖片的大小,防止coder使用第三方layout,沒有設(shè)置大小
* @param clrs 漸變顏色的數(shù)組
* @param percent 漸變顏色的占比數(shù)組
* @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擴大按鈕點擊區(qū)域
按鈕擴大點擊區(qū)域续镇,具體原理可查看iOS中觸摸事件傳遞和響應(yīng)原理
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface ExpandTouchButton : UIButton
/**
擴大熱區(qū)范圍 例如上下左右各擴大10 (-10 , -10, -10 , -10) 如果設(shè)置正值則會將按鈕可點擊區(qū)域縮小
*/
@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
示例:
/**
* 擴大按鈕點擊區(qū)域
*/
- (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(@"按鈕被點擊了-----------");
}