先准备一张图片添加到Assets.xcassets中
常规按钮上图片内容和文本内容的位置
通过titleLabel.frame和imageView.frame来修改图片内容和文本内容的位置(不会成功)
- (void)viewDidLoad {
[super viewDidLoad];
UIButton *greenBt = [UIButton buttonWithType:UIButtonTypeCustom];
greenBt.frame = CGRectMake(0, 0, 150, 70);
greenBt.center = CGPointMake(self.view.center.x, 200);
greenBt.backgroundColor = [UIColor grayColor];
[greenBt setTitle:@"按钮二" forState:UIControlStateNormal];
[greenBt setImage:[UIImage imageNamed:@"icon"] forState:UIControlStateNormal];
greenBt.imageView.backgroundColor = [UIColor redColor];
greenBt.titleLabel.backgroundColor = [UIColor purpleColor];
// 改变位置
greenBt.titleLabel.frame = CGRectMake(0, 0, 100, 70);
greenBt.imageView.frame = CGRectMake(100, 0, 70, 70);
[self.view addSubview:greenBt];
}
运行效果:
注意:在按钮外面修改的尺寸,按钮的内部都会覆盖掉
正确修改按钮图片内容和文本内容的位置的两种方法
创建一个MyButton的类继承UIButton
- 通过重新titleRectForContentRect: 和 imageRectForContentRect:
#pragma mark - 方法一
/*
重新titleRectForContentRect: 和 imageRectForContentRect:
这两个方法修改文本内容位置和图片内容位置
*/
// 修改文本内容位置
- (CGRect)titleRectForContentRect:(CGRect)contentRect{
return CGRectMake(0, 0, 100, 70);
}
// 修改图片内容位置
- (CGRect)imageRectForContentRect:(CGRect)contentRect{
return CGRectMake(100, 0, 70, 70);
}
- 通过重写layoutSubviews
#pragma mark - 方法二
- (void)layoutSubviews{
[super layoutSubviews];
// 从新布局文本内容titleLabel
self.titleLabel.frame = CGRectMake(0, 0, 100, 70);
// 从新布局图片内容imageView
self.imageView.frame = CGRectMake(100, 0, 70, 70);
}
在ViewController 使用
- (void)viewDidLoad {
[super viewDidLoad];
MyButton *greenBt = [MyButton buttonWithType:UIButtonTypeCustom];
greenBt.frame = CGRectMake(0, 0, 150, 70);
greenBt.center = CGPointMake(self.view.center.x, 200);
greenBt.backgroundColor = [UIColor grayColor];
[greenBt setTitle:@"按钮二" forState:UIControlStateNormal];
[greenBt setImage:[UIImage imageNamed:@"icon"] forState:UIControlStateNormal];
greenBt.imageView.backgroundColor = [UIColor redColor];
greenBt.titleLabel.backgroundColor = [UIColor purpleColor];
[self.view addSubview:greenBt];
}
运行效果:
运行效果看起来有点丑
重写initWithFrame方法优化MyButton效果
- (instancetype)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self != nil) {
// 设置文本居中
self.titleLabel.textAlignment = NSTextAlignmentCenter;
// 设置图片的内容模式
self.imageView.contentMode = UIViewContentModeCenter;
}
return self;
}
运行效果:
当同时使用重写titleRectForContentRect: 、 imageRectForContentRect: 方法和重写layoutSubviews方法时
#pragma mark - 方法一
/*
重新titleRectForContentRect: 和 imageRectForContentRect:
这两个方法修改文本内容位置和图片内容位置
*/
// 修改文本内容位置
- (CGRect)titleRectForContentRect:(CGRect)contentRect{
return CGRectMake(0, 0, 100, 70);
}
// 修改图片内容位置
- (CGRect)imageRectForContentRect:(CGRect)contentRect{
return CGRectMake(100, 0, 70, 70);
}
#pragma mark - 方法二
- (void)layoutSubviews{
[super layoutSubviews];
// 从新布局文本内容titleLabel
self.titleLabel.frame = CGRectMake(70, 0, 100, 70);
// 从新布局图片内容imageView
self.imageView.frame = CGRectMake(0, 0, 70, 70);
}
运行效果:
最终运行的效果显示,文本内容和图片内容的位置是按照layoutSubviews中设置的数据显示的,说明layoutSubviews是最后执行的方法。打印它们执行的顺序:
-[MyButton titleRectForContentRect:]
-[MyButton imageRectForContentRect:]
-[MyButton layoutSubviews]
对其他控件内容位置不满意也可以在layoutSubviews修改内容布局。
MyButton 类的相关代码
MyButton.h 文件
#import <UIKit/UIKit.h>
@interface MyButton : UIButton
@end
MyButton.m 文件
#import "MyButton.h"
@implementation MyButton
- (instancetype)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self != nil) {
// 设置文本居中
self.titleLabel.textAlignment = NSTextAlignmentCenter;
// 设置图片的内容模式
self.imageView.contentMode = UIViewContentModeCenter;
}
return self;
}
#pragma mark - 方法一
/*
重新titleRectForContentRect: 和 imageRectForContentRect:
这两个方法修改文本内容位置和图片内容位置
*/
// 修改文本内容位置
- (CGRect)titleRectForContentRect:(CGRect)contentRect{
NSLog(@"%s",__func__);
return CGRectMake(0, 0, 100, 70);
}
// 修改图片内容位置
- (CGRect)imageRectForContentRect:(CGRect)contentRect{
NSLog(@"%s",__func__);
return CGRectMake(100, 0, 70, 70);
}
#pragma mark - 方法二
- (void)layoutSubviews{
[super layoutSubviews];
NSLog(@"%s",__func__);
// 从新布局文本内容titleLabel
self.titleLabel.frame = CGRectMake(70, 0, 100, 70);
// 从新布局图片内容imageView
self.imageView.frame = CGRectMake(0, 0, 70, 70);
}
@end
修改Button的内边距
按钮的内边距是指图片与文本之间的间距,图片与按钮边缘的间距,文本与按钮边缘的边距。
默认按钮形状:
设置按钮内边距的方法
-
在xib中之间设置
-
设置content边距
-
设置title边距
-
设置image边距
-
content、title、image三个的边距可以同时使用。
- 通过代码改变间距:
@interface ViewController ()
//xib中拖线的按钮
@property (weak, nonatomic) IBOutlet UIButton *edgeBt;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
_edgeBt.imageView.backgroundColor = [UIColor redColor];
_edgeBt.titleLabel.backgroundColor = [UIColor purpleColor];
/*
UIEdgeInsets UIEdgeInsetsMake(CGFloat top, CGFloat left, CGFloat bottom, CGFloat right)
*/
//内容边距
_edgeBt.contentEdgeInsets = UIEdgeInsetsMake(-20, 0, 0, 0);
//文本边距
_edgeBt.titleEdgeInsets = UIEdgeInsetsMake(0, 30, 0, 0);
//文本边距
_edgeBt.imageEdgeInsets = UIEdgeInsetsMake(0, 0, 0, 20);
}
运行效果:
网友评论
这只是提供一种方法
要灵活改变Frame做法比较多,你可以在layoutSubviews设置他们的Frame根据button的Frame改变
也可以提供修改Frame的方法比如:
- (void)setTitleLabelFrame:(CGRect )frame;
- (void)setImageFrame:(CGRect )frame;
实现:#pragma mark - 方法二
- (void)layoutSubviews{
[super layoutSubviews];
NSLog(@"%s",__func__);
// 从新布局文本内容titleLabel
if (CGRectEqualToRect(_titleFrame, CGRectZero)) {
self.titleLabel.frame = CGRectMake(70, 0, 100, 70);
} else {
self.titleLabel.frame = _titleFrame;
}
// 从新布局图片内容imageView
if (CGRectEqualToRect(_imageFrame, CGRectZero)) {
self.imageView.frame = CGRectMake(0, 0, 70, 70);
} else {
self.imageView.frame = _imageFrame;
}
}
- (void)setTitleLabelFrame:(CGRect)frame{
_titleFrame = frame;
[self layoutSubviews];
}
- (void)setImageFrame:(CGRect)frame {
_imageFrame = frame;
[self layoutSubviews];
}
调用
- (void)chageFrame:(MyButton *)bt{
[bt setTitleLabelFrame:CGRectMake(0, 0, 170, 20)];
[bt setImageFrame:CGRectMake(0, 20, 170, 50)];
NSLog(@"%s",__func__);
}
这边只是说一下改变的思路,具体各种情况,只有细微优化就行了。
在layout方法里面直接修改frame就行了
比如:
self.titleLabel.frame = CGRectMake(0, 50, 170, 20);
self.imageView.frame = CGRectMake(0, 50, 70, 20);
这样显示的就是上下结构的
#pragma mark - 方法二
- (void)layoutSubviews{
[super layoutSubviews];
NSLog(@"%s",__func__);
// 从新布局文本内容titleLabel
self.titleLabel.frame = CGRectMake(0, 50, 170, 20);
// 从新布局图片内容imageView
self.imageView.frame = CGRectMake(0, 50, 70, 20);
}