UIButton的图文排列
图文结合
通过 setTitle:forState:
和 setImage:forState:
这两个方法设置了 UIButton 的 标题和图片之后,可以通过以下两个属性访问代表 UIButton 中标题和图片的两个子控件:
@property(nullable, nonatomic,readonly,strong) UILabel *titleLabel;
@property(nullable, nonatomic,readonly,strong) UIImageView *imageView;
UIControlContentVerticalAlignment
UIControlContentVerticalAlignment
控制的是UIButton
的image
和title
在竖直方向的对齐方式,其值有top
、bottom
、center
、fill
。当指定为fill
时,图片会在竖直方向被拉伸填满UIButton
的高度。
// UIButton的image和title在竖直方向的对齐方式
typedef NS_ENUM(NSInteger, UIControlContentVerticalAlignment) {
UIControlContentVerticalAlignmentCenter = 0,
UIControlContentVerticalAlignmentTop = 1,
UIControlContentVerticalAlignmentBottom = 2,
UIControlContentVerticalAlignmentFill = 3,
};
UIControlContentHorizontalAlignment
UIControlContentHorizontalAlignment
控制的则是水平方向的对齐方式。其值有left
、right
、center
、fill
。当指定为fill
时,图片并没有在水平方向将UIButton
充满,而是在右侧留出了一定距离,这个距离应该是title
的宽度,但是title
实际上也没有乖乖的跑到那段空隙去,而是和image
重叠了
typedef NS_ENUM(NSInteger, UIControlContentHorizontalAlignment) {
UIControlContentHorizontalAlignmentCenter = 0,
UIControlContentHorizontalAlignmentLeft = 1,
UIControlContentHorizontalAlignmentRight = 2,
UIControlContentHorizontalAlignmentFill = 3,
};
- UIEdgeInsets
使用 insets 来添加或删除你自定义(或系统的)按钮内容周围空间,你可以单独为按钮标题(
titleEdgeInsets
)、图片(imageEdgeInsets
)或同时为标题和图片(contentEdgeInsets
)指定 insets 值。应用时,insets 影响了按钮的相应内容矩形,由Auto Layout引擎用于确定按钮的位置。
@property(nonatomic) UIEdgeInsets contentEdgeInsets;
@property(nonatomic) UIEdgeInsets titleEdgeInsets;
@property(nonatomic) UIEdgeInsets imageEdgeInsets;
默认按钮布局
创建一个图片+标题的按钮:
// 创建自定义类型按钮
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(80, 180, 150, 150);
// 设置按钮的背景颜色
button.backgroundColor = [UIColor honeydewColor];
// 设置按钮的标签文字
[button setTitle:@"Tap it" forState:UIControlStateNormal];
button.titleLabel.backgroundColor = [UIColor skyBlueColor];
// 设置按钮图片
UIImage *image = [UIImage imageNamed:@"buttonImage"];
[button setImage:image forState:UIControlStateNormal];
[self.view addSubview:button];
默认情况下:图片在左边而文字在右边,而且整体水平和垂直居中。
这是一个 UIButton 范畴(Category) 类,用于处理图文结合
- UIButton+ImageTitleStyle.h 文件
#import <UIKit/UIKit.h>
@interface UIButton (ImageTitleStyle)
//上下居中,图片在上,文字在下
- (void)verticalCenterImageAndTitle:(CGFloat)spacing;
- (void)verticalCenterImageAndTitle; //默认6.0
//左右居中,文字在左,图片在右
- (void)horizontalCenterTitleAndImage:(CGFloat)spacing;
- (void)horizontalCenterTitleAndImage; //默认6.0
//左右居中,图片在左,文字在右
- (void)horizontalCenterImageAndTitle:(CGFloat)spacing;
- (void)horizontalCenterImageAndTitle; //默认6.0
//文字居中,图片在左边
- (void)horizontalCenterTitleAndImageLeft:(CGFloat)spacing;
- (void)horizontalCenterTitleAndImageLeft; //默认6.0
//文字居中,图片在右边
- (void)horizontalCenterTitleAndImageRight:(CGFloat)spacing;
- (void)horizontalCenterTitleAndImageRight; //默认6.0
@end
- UIButton+ImageTitleStyle.m 文件
#import "UIButton+ImageTitleStyle.h"
@implementation UIButton (ImageTitleStyle)
#pragma mark - 上下居中,图片在上,文字在下
- (void)verticalCenterImageAndTitle:(CGFloat)spacing
{
// get the size of the elements here for readability
CGSize imageSize = self.imageView.frame.size;
CGSize titleSize = self.titleLabel.frame.size;
// lower the text and push it left to center it
self.titleEdgeInsets = UIEdgeInsetsMake(0.0, - imageSize.width, - (imageSize.height + spacing/2), 0.0);
// the text width might have changed (in case it was shortened before due to
// lack of space and isn't anymore now), so we get the frame size again
titleSize = self.titleLabel.frame.size;
// raise the image and push it right to center it
self.imageEdgeInsets = UIEdgeInsetsMake(- (titleSize.height + spacing/2), 0.0, 0.0, - titleSize.width);
}
- (void)verticalCenterImageAndTitle
{
const int DEFAULT_SPACING = 6.0f;
[self verticalCenterImageAndTitle:DEFAULT_SPACING];
}
#pragma mark - 左右居中,文字在左,图片在右
- (void)horizontalCenterTitleAndImage:(CGFloat)spacing
{
// get the size of the elements here for readability
CGSize imageSize = self.imageView.frame.size;
CGSize titleSize = self.titleLabel.frame.size;
// lower the text and push it left to center it
self.titleEdgeInsets = UIEdgeInsetsMake(0.0, - imageSize.width, 0.0, imageSize.width + spacing/2);
// the text width might have changed (in case it was shortened before due to
// lack of space and isn't anymore now), so we get the frame size again
titleSize = self.titleLabel.frame.size;
// raise the image and push it right to center it
self.imageEdgeInsets = UIEdgeInsetsMake(0.0, titleSize.width + spacing/2, 0.0, - titleSize.width);
}
- (void)horizontalCenterTitleAndImage
{
const int DEFAULT_SPACING = 6.0f;
[self horizontalCenterTitleAndImage:DEFAULT_SPACING];
}
#pragma mark - 左右居中,图片在左,文字在右
- (void)horizontalCenterImageAndTitle:(CGFloat)spacing;
{
// get the size of the elements here for readability
// CGSize imageSize = self.imageView.frame.size;
// CGSize titleSize = self.titleLabel.frame.size;
self.titleEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, 0.0, - spacing/2);
self.imageEdgeInsets = UIEdgeInsetsMake(0.0, - spacing/2, 0.0, 0.0);
}
- (void)horizontalCenterImageAndTitle;
{
const int DEFAULT_SPACING = 6.0f;
[self horizontalCenterImageAndTitle:DEFAULT_SPACING];
}
#pragma mark - 文字居中,图片在左边
- (void)horizontalCenterTitleAndImageLeft:(CGFloat)spacing
{
// get the size of the elements here for readability
// CGSize imageSize = self.imageView.frame.size;
// CGSize titleSize = self.titleLabel.frame.size;
self.imageEdgeInsets = UIEdgeInsetsMake(0.0, - spacing, 0.0, 0.0);
}
- (void)horizontalCenterTitleAndImageLeft
{
const int DEFAULT_SPACING = 6.0f;
[self horizontalCenterTitleAndImageLeft:DEFAULT_SPACING];
}
#pragma mark - 文字居中,图片在右边
- (void)horizontalCenterTitleAndImageRight:(CGFloat)spacing
{
// get the size of the elements here for readability
CGSize imageSize = self.imageView.frame.size;
CGSize titleSize = self.titleLabel.frame.size;
// lower the text and push it left to center it
self.titleEdgeInsets = UIEdgeInsetsMake(0.0, - imageSize.width, 0.0, 0.0);
// the text width might have changed (in case it was shortened before due to
// lack of space and isn't anymore now), so we get the frame size again
titleSize = self.titleLabel.frame.size;
// raise the image and push it right to center it
self.imageEdgeInsets = UIEdgeInsetsMake(0.0, titleSize.width + imageSize.width + spacing, 0.0, - titleSize.width);
}
- (void)horizontalCenterTitleAndImageRight
{
const int DEFAULT_SPACING = 6.0f;
[self horizontalCenterTitleAndImageRight:DEFAULT_SPACING];
}
1. 上下居中,图片在上,文字在下
[button verticalCenterImageAndTitle:10.0f];
2. 左右居中,文字在左,图片在右
[button horizontalCenterTitleAndImage:10.0f];
3. 左右居中,图片在左,文字在右
[button horizontalCenterImageAndTitle:10.0f];
通过布局子视图方法:
当 UIButton 是固定大小时,使用上面的方法无法设置按钮中的图片相对于整个按钮的大小。
- 图片在上、文字在下
- (void) layoutSubviews {
[super layoutSubviews];
// 修改button内image和label的位置
self.imageView.y = self.height * 0.15;
self.imageView.width = self.width * 0.5;
self.imageView.height = self.imageView.width;
self.imageView.centerX = self.width * 0.5;
self.titleLabel.x = 0;
self.titleLabel.y = self.imageView.bottom;
self.titleLabel.width = self.width;
self.titleLabel.height = self.height - self.imageView.bottom;
}
显示/隐藏密码按钮
- (UIButton *)showPasswordButton {
if (!_showPasswordButton) {
_showPasswordButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_showPasswordButton setImage:[UIImage imageNamed:@"login_pwd_hide"]
forState:UIControlStateNormal];
[_showPasswordButton setImage:[UIImage imageNamed:@"login_pwd_show"]
forState:UIControlStateSelected];
[_showPasswordButton setSelected:NO];
[_showPasswordButton addTarget:self
action:@selector(showPasswordButtonDidClicked:)
forControlEvents:UIControlEventTouchUpInside];
}
return _showPasswordButton;
}
- (void)showPasswordButtonDidClicked:(id)sender {
self.passwordTextField.secureTextEntry = !self.passwordTextField.secureTextEntry;
[self.showPasswordButton setSelected:!self.passwordTextField.secureTextEntry];
}