了解 UIButton 的 UIEdgeInsets 属性

在应用开发时,经常会用到 UIButton 这个控件。在UI的样式上,它支持仅图片、仅文字、图片+文字(默认的左图右文形式)。但是在一些场景下常常需要对原生的 UIButton 进行一些调整。例如:调整图片和文字的距离、上图下文等形式。这个时候就要借助于 UIButton 的 UIEdgeInsets 属性了。然而,这个属性的过程中,常常会遇到设置不生效的情况。这是因为对这个属性了解的还不够,本文就是针对 UIEdgeInsets 的一些基本的使用说明。

UIEdgeInsets 的种类

这里所说的 UIEdgeInsets 仅仅是针对 UIButton 的。

1
2
3
typedef struct UIEdgeInsets {
CGFloat top, left, bottom, right;
} UIEdgeInsets;

结构体,参数分别表示距离上、左、下、右四个边界的距离,它的默认值为0.

UIButton 中的 UIEdgeInsets 属性主要有三个:

1. contentEdgeInsets

这个属性是 UILabel + UIImageView 整体的偏移。如果要将 button 中的内容整体偏移15。写法如下

1
button.contentEdgeInsets = UIEdgeInsetsMake(15, 15, -15, -15);

2. titleEdgeInsets

这个代表的是 title 的 UIEdgeInsets,其中的 top、bottom、right 是相对于外层的 contentView 的,而 left 是相对于 image 来说的。

3. imageEdgeInsets

这个代表的是 image 的 UIEdgeInsets,其中的top、bottom、left 是相对于外层的 contentView 的,而 right 是相对于 title 来说的。

造成 imageEdgeInsets 和 titleEdgeInsets 出现这种情况的原因是,UIButton 默认的图文按钮是左图右文的形式。

在上图中 top、left、bottom、right 在沿着箭头方向上的位移为正值,逆着箭头方向的值为负值。

UIEdgeInsets 的简单应用

实现左文右图

调整 imageEdgeInsets 向右偏移 title 的宽度,titleEdgeInsets 向左偏移 image 的宽度,形成如下的按钮:

1
2
3
4
CGRect rectTitle = button.titleLabel.frame;
CGRect rectImage = button.imageView.frame;
button.titleEdgeInsets = UIEdgeInsetsMake(0, - rectImage.size.width, 0, rectImage.size.width);
button.imageEdgeInsets = UIEdgeInsetsMake(0, rectTitle.size.width, 0, - rectTitle.size.width);

实现上图下文

调整 imageEdgeInsets 向右偏移 title 宽度的一半,向上偏移 title 高度的一半;titleEdgeInsets 向左偏移 image 宽度的一半,向下偏移 image 高度的一半。形成如下的按钮:

1
2
3
4
CGRect rectTitle = button.titleLabel.frame;
CGRect rectImage = button.imageView.frame;
button.titleEdgeInsets = UIEdgeInsetsMake(rectImage.size.height / 2, - rectImage.size.width/2, -rectImage.size.height / 2 , rectImage.size.width/2);
button.imageEdgeInsets = UIEdgeInsetsMake(- rectTitle.size.height / 2, rectTitle.size.width/2, rectTitle.size.height / 2, -rectTitle.size.width/2);

UIEdgeInsets 的简单分析

在上面的应用中可以发现t op = - bottom、left = - right,这时候的位移值直接从 top 和 left 的值就可以看出,但是当 top != - bottom, left != - right 时,实际的偏移量就不是很直观了。而且如果随意取值的话往往会出现一些非正常的效果,所以尽量比较规范的使用 UIEdgeInsets。