UIButton实现图片和文字自定义排列

我们在开发的时候经常遇到一个需求就是需要创建一个按钮同时可以放图片和文字,实现这个需求可以有很多种方法:

logo
  • 比如创建一个UIView然后添加UIImageViewUILable,最后给他添加一个单击的手势。
  • 再比如自定义一个UIButton,在上边添加UIImageViewUILabel
  • 当然,我们也可以用系统的UIButton直接设置图片和文字,但是使用系统的UIButton时如何摆放图片和文字的位置就需要好好研究一下。

所以这篇文章就写一下如何来摆放系统UIButton中的图片和文字。

准备

UIButton中有两个方法用来设置图片和按钮的边界约束:

1
2
@property(nonatomic) UIEdgeInsets titleEdgeInsets;
@property(nonatomic) UIEdgeInsets imageEdgeInsets;

通过设置这两个参数我们就能设置图片和按钮的位置,从而实现 图片在上文字在下、图片在下文字在上、图片在左文字在右和图片在右文字在左的样式。

默认情况下图片是在左边,文字在右边的。

logo

接下来这段非常重要

图片的上、下、左约束是相对于UIButton的,而右是相对于文字的:

logo

文字的上、下、右约束是相对于UIButton的,而左是相对于图片的:

logo

开搞

首先我们先确定几个参数:

  • 按钮大小:这个不用说了,如果想要通过这种方法排列图片和文字就一定要先确定好按钮的大小。

    1
    CGSize buttonSize = self.frame.size;
  • 文字大小:UIButton有自己的titleLabel,所我们设置好文字之后直接获取titleLabel的大小就可以了。

    1
    CGSize titleSize = self.titleLabel.intrinsicContentSize;
  • 图片大小:这个和文字一样,我们设置好图片之后直接获取imageView的大小就可以了。

    1
    CGSize imageSize = self.imageView.frame.size;
  • 图片和文字之间的空隙:我们肯定不是希望图片和文字紧贴在一起吧,所以设置一个图片和文字之间的空隙大小是有必要的。

    1
    CGFloat buttonSpace = 10.0;

图片在上,文字在下

设置垂直方向的排列时我们还需要获取一个参数,就是按钮和文字、图片垂直空间上上下两边的空隙。

logo

这个空隙的大小就是按钮的高度减去图片和文字以及中间空隙的高度除2获得的。

1
CGFloat verticalSpace = (buttonSize.height - titleSize.height - imageSize.height - buttonSpace)/2.0;

接下来就是设置图片和文字的边界了

图片边界:
  • 上:上边界不用说了,相对于按钮,所以直接设置成垂直空隙大小就可以了。

  • 左:左侧因为也是相对于按钮,为了让图片居中,就直接设置成(按钮宽度-图片宽度)/2就可以了。

  • 下:下边界也是相对于按钮,因为图片在上,所以设置成垂直(空隙大小+文字高度+空隙)就可以了。

  • 右:右侧是比较重要的约束,因为右侧是相对与文字的,我们可以理解成如果没有文字,右侧的空间应该和左侧一样(按钮宽度-图片宽度)/2,但是因为多了文字,这样设置就会导致位置出现偏差,所以要减去文字的宽度。

这样一来,图片的边界就设置好了。

文字边界:
  • 上:上边界同样是相对按钮的,因为文字在下,所以设置成(空隙大小+图片高度+空隙)就可以了。

  • 左:理解了前边的图片,文字也是一样,所以左侧的空间约束应为(按钮宽度-文字宽度)/2再减去图片的宽度。

  • 下:下没什么好说的了,相对于按钮,所以为垂直方向的空隙。

  • 右:右侧也是相对于按钮,所以直接设置成(按钮宽度-文字宽度)/2就可以了。

这样设置了之后,文字和图片的位置就设置好了。

1
2
3
4
5
6
7
8
9
10
11
12
//上下空余的间隙
CGFloat verticalSpace = (buttonSize.height - titleSize.height - imageSize.height - buttonSpace)/2.0;
[self setImageEdgeInsets:UIEdgeInsetsMake(verticalSpace,
(buttonSize.width-imageSize.width)/2.0,
verticalSpace + titleSize.height + buttonSpace,
(buttonSize.width-imageSize.width)/2.0-titleSize.width)];
[self setTitleEdgeInsets:UIEdgeInsetsMake(verticalSpace + imageSize.height + buttonSpace,
(buttonSize.width - titleSize.width)/2.0 - imageSize.width,
verticalSpace,
(buttonSize.width - titleSize.width)/2.0)];
logo
logo

图片在左,文字在右

这个情况是系统默认的情况,所以我们基本不需要做处理,只需要把图片右侧相对于文字的空隙和文字左侧相对于图片的空隙都设置为我们设置的空隙就可以了。

1
2
3
4
5
6
7
8
9
[self setImageEdgeInsets:UIEdgeInsetsMake(0,
0,
0,
buttonSpace)];
[self setTitleEdgeInsets:UIEdgeInsetsMake(0,
buttonSpace,
0,
0)];
logo
logo

图片在右,文字在左

这个情况和上边的情况类似,只不过文字和图片调换了位置,所以我们把他们互相约束的大小改成负的(图片宽度+文字宽度+空隙)就可以了。

1
2
3
4
5
6
7
8
9
[self setImageEdgeInsets:UIEdgeInsetsMake(0,
0,
0,
-(imageSize.width + titleSize.width + buttonSpace))];
[self setTitleEdgeInsets:UIEdgeInsetsMake(0,
-(imageSize.width + titleSize.width + buttonSpace),
0,
0)];
logo
logo

图片在下,文字在上

这个情况和第一种情况(图片在上,文字在下)类似,只不过是文字和图片在垂直方向上调换了一下位置,左右的约束都没有改变,所以也就不详细说了,理解了第一种情况应该就很好理解这中情况。

1
2
3
4
5
6
7
8
9
10
11
CGFloat verticalSpace = (buttonSize.height - titleSize.height - imageSize.height - buttonSpace)/2.0;
[self setImageEdgeInsets:UIEdgeInsetsMake(verticalSpace + titleSize.height + buttonSpace,
(buttonSize.width-imageSize.width)/2.0,
verticalSpace,
(buttonSize.width-imageSize.width)/2.0-titleSize.width)];
[self setTitleEdgeInsets:UIEdgeInsetsMake(verticalSpace,
(buttonSize.width - titleSize.width)/2.0 - imageSize.width,
verticalSpace + imageSize.height + buttonSpace,
(buttonSize.width - titleSize.width)/2.0)];
logo
logo

结束

其实这个边界的东西很好理解,只要想通了一个,其他方向的就很好控制了。
以上的内容都是我自己研究出来的结果,如果有哪些地方不对,还希望有大神能够批评指正。
那今天就这样了~

啊对了!Demo地址在这里