这篇文章整理了一下UIButton的各种EdgeInsets都咋用,有啥效果。留着自己以后对此迷糊时再看一看,也希望能对你有所帮助喔😜。
达成共识
如果没有给UIButton
的宽和高一个固定值,那么UIButon
的大小将自动调整为正好放下 title
和image
。这个苹果官方文档有提到,而且在Storyboard中一试便知。此外,默认情况下图片在左,文字在右。
没有给固定宽和高,给UIButton
设置了一个image
和title
,运行的结果如下:
UIControlContent Vertical/Horizontal Alignment
在开始说EdgeInsets
之前,先说说UIControlContentVerticalAlignment
和UIControlContentHorizontalAlignment
产生的效果,因为这两个属性的设置也会对UIButton
的效果有一定影响,而且跟后面EdgeInsets
的计算也有关系。
UIControlContentVerticalAlignment
控制的是UIButton
的image
和title
在竖直方向的对齐方式,其值有top
、bottom
、 center
、fill
。当指定为fill
时,图片会在竖直方向被拉伸填满UIButton的高度。
为了效果明显,我给上面的那个按钮设置了一个较大的宽高,当取各种值时,效果如下:
的对齐方式。其值有left
、right
、center
、fill
。当指定为fill
时,图片并没有在水平方向将UIButton
充满,而是在右侧留出了一定距离,这个距离应该是title
的宽度,但是title
实际上也没有乖乖的跑到那段空隙去,而是和image
重叠了╮(╯▽╰)╭
当取各种值时,效果如下:
UIControlContentHorizontalAlignment
控制的则是水平方向
UIEdgeInsets
UIButton
共有3个与UIEdgeInsets
相关的属性:
imageEdgeInsets
调整image
的上下左右边缘离开原来位置的距离,该调整并不会改变UIButton
原来的大小,image
为了适应调整,可能会变形或者跑出UIButton
的外面。
titleEdgeInsets
调整title
的上下左右边缘离开原来位置的距离,该调整并不会改变UIButton
原来的大小,title为了适应调整,文字可能显示不全或者跑出UIButton
的外面。
contentEdgeInsets
调整UIButton
本身的上下左右边缘离开原来位置的距离,该调整会改变UIButton
的大小。
这个3个属性的默认值都是.zero
。
UIEdgeInsets
由top
、left
、 bottom
、right
构成,对于imageEdgeInsets
和titleEdgeInsets
来说:
top
为正值时,控件会相对原来所在的位置下移相应值,控件的顶部边缘会在原来位置的下方相应值。top
为负值时,控件会相对原来的位置上移相应值,控件的顶部边缘会在原来位置的上方相应值。
left
为正值时,控件会相对原来所在的位置右移相应值,控件的左侧边缘会在原来位置的右方相应值。left
为负值时,控件会相对原来的位置左移相应值,控件的左侧边缘会在原来位置的左方相应值。
bottom
为正值时,控件会相对原来所在的位置上移相应值,控件的底部边缘会在原来位置的上方相应值。bottom
为负值时,控件会相对原来的位置下移相应值,控件的底部边缘会在原来位置的下方相应值。
right
为正值时,控件会相对原来所在的位置左移相应值,控件的右侧边缘会在原来位置的左方相应值。right
为负值时,控件会相对原来位置右移相应值,控件的右侧边缘会在原来位置的右方相应值。
对于contentEdgeInsets
来说,当top
、left
、bottom
、right
为正值时,会使UIButton
向四周扩展变大。为负值时,会使UIButton
向内收缩变小。哈哈,这样好记一些😄
现在把UIButton
的固定大小去掉,让它自己自适应。先来一个水平方向调整的:
yellowButton.contentHorizontalAlignment = .left
yellowButton.contentVerticalAlignment = .center
yellowButton.imageEdgeInsets = UIEdgeInsetsMake(0, 20, 0, 0)
yellowButton.titleEdgeInsets = UIEdgeInsetsMake(0, 20, 0, 0)
第一张图只设置了
imageEdgeInsets
,没有设置titleEdgeInsets
,第三张两者都设置了。可以看到,imageEdgeInsets
和titleEdgeInsets
并不会互相影响,第一张图中image
跟title
重合了,并没有把title
往右挤了相应距离。第二张和第四张看到,image
和title
本身被压缩了。
还有一点值得注意的是,如果原来UIButton
的大小能容纳下调整后的image
和title
,它们将不会被压缩。像第一张那样,image
左移后还是放得下的,所以没有被压缩,title
却放不下了,所以被压缩了。为什么说是原来的大小呢,因为调整contentEdgeInsets
也会使UIButton
变大,但是image
和title
却不会因此而不被压缩。再来一个竖直方向调整的:
yellowButton.contentHorizontalAlignment = .center
yellowButton.contentVerticalAlignment = .top
yellowButton.imageEdgeInsets = UIEdgeInsetsMake(20, 0, 0, 0)
yellowButton.titleEdgeInsets = UIEdgeInsetsMake(20, 0, 0, 0)
第一张图仍然是只调整了
imageEdgeInsets
的效果。
从上面的结果可以看到调整imageEdgeInsets
和titleEdgeInsets
并不会改变UIButton
的大小,而导致有时图片被压缩,或者文字显示不下。这时就要接着用UIButton
的另一个属性contentEdgeInsets
来调整了。
yellowButton.contentHorizontalAlignment = .left
yellowButton.contentVerticalAlignment = .center yellow
Button.imageEdgeInsets = UIEdgeInsetsMake(0, 20, 0, 0)
yellowButton.titleEdgeInsets = UIEdgeInsetsMake(0, 20, 0, 0)yellowButton.contentEdgeInsets = UIEdgeInsetsMake(0, 0, 0, 20)
好吧,结果并不如我们想象的一样,
UIButton
是变大了,但是image
和
title
并没有自己调整,还是一个压缩的状态。验证了上面值得注意的那一点~ 这时候要再调整一下它们的right
值了,将其设置为-20,如愿得到了下面的结果。
需要注意 当设置contentHorizontalAlignment
为.left
时,再设置imageEdgeInsets
和titleEdgeInsets
的.right
为负值时,如果image
和title
原来是压缩状态,会对其调整。如果原来是正常状态,则不会产任何影响。也就是说,imageEdgeInsets
和titleEdgeInsets
的设置并不会让image
和title
被拉伸!其他方向亦如此~所以,为了保证image
和title
始终不被压缩,.left
设置了多少正值,.right
就设置多少负值。上下方向也一样。
实战
上面做了这么多铺垫,现在通过设置UIButton
的3个EdgeInsets
属性来实现一些我们想要的效果吧😉
在做水平方向的调整时,最好将contentHorizontalAlignment
设置为.left
,这样改动就从左开始。在做竖直方向的调整时,最好将contentVerticalAlignment
设置为.top
,这样改动就从上面开始。对于自己在设置时,比较容易在脑子想象每个值设置完的样子😁
例1:设置一个四周间隔20,image和title之间间隔20的button。
计算过程如下:
//向的调整,设为靠左对齐
yellowButton.contentHorizontalAlignment = .left
yellowButton.contentVerticalAlignment = .center //image左移20
yellowButton.imageEdgeInsets = UIEdgeInsetsMake(0, 20, 0, -20)//title左移20,并且与image之间间隔20
yellowButton.titleEdgeInsets = UIEdgeInsetsMake(0, 40, 0, -40)//image左移20,已经使button左侧的间隔是20了
yellowButton.contentEdgeInsets = UIEdgeInsetsMake(20, 0, 20, 60)
最后,完美😂
例2:设置一个image在上居中,title在下居中,两者之间间距20,四周间距20的button。
这个看起来复杂一些,但也只是计算复杂一些~ 计算过程如下,求出标记问号的距离就行了:
//设置水平和竖直的对齐方式
yellowButton.contentHorizontalAlignment = .left
yellowButton.contentVerticalAlignment = .top
let imageRect = yellowButton.imageView!.framelet
let titleRect = yellowButton.titleLabel!.framelet
let buttonRect = yellowButton.frame //图中?1的值
let image_l = (buttonRect.size.width-imageRect.size.width)/2//确定image的位置
yellowButton.imageEdgeInsets = UIEdgeInsetsMake(20, image_l, -20, -image_l)//图中?2的值
let title_l = imageRect.size.width-(buttonRect.size.width-titleRect.size.width)/2//图中?3的值
let title_t = imageRect.size.height+40//title的位置可以确定了
yellowButton.titleEdgeInsets = UIEdgeInsetsMake(title_t, -title_l, -title_t, title_l)//图中?4的值
let button_b = titleRect.size.height+60//计算图中?5的值
let max_w = max(titleRect.size.width, imageRect.size.width)
let button_l = -(buttonRect.size.width-(max_w+20*2))/2//button要调整的大小确定了
yellowButton.contentEdgeInsets = UIEdgeInsetsMake(0, button_l, button_b, button_l)
运行后的结果:
了解imageEdgeInsets
、titleEdgeInsets
、contentEdgeInsets
后,就可以随心所欲的来设置自己的button
了。
至此,总结完毕😆
–End–
文章来源于意林的bolg的技术博客,意林授权
传送门:http://shinancao.github.io/2016/12/15/iOS-UIButton-EdgeInsets/