美文网首页
理解UIButton的各种EdgeInsets

理解UIButton的各种EdgeInsets

作者: 陈大威 | 来源:发表于2016-12-19 18:21 被阅读1288次

    这篇文章整理了一下UIButton的各种EdgeInsets都咋用,有啥效果。留着自己以后对此迷糊时再看一看,也希望能对你有所帮助喔😜。

    达成共识

    如果没有给UIButton的宽和高一个固定值,那么UIButon
    的大小将自动调整为正好放下 titleimage。这个苹果官方文档有提到,而且在Storyboard中一试便知。此外,默认情况下图片在左,文字在右。
    没有给固定宽和高,给UIButton设置了一个imagetitle,运行的结果如下:

    ButtonEdgeInsets.jpg

    UIControlContent Vertical/Horizontal Alignment

    在开始说EdgeInsets之前,先说说UIControlContentVerticalAlignmentUIControlContentHorizontalAlignment产生的效果,因为这两个属性的设置也会对UIButton的效果有一定影响,而且跟后面EdgeInsets的计算也有关系。

    UIControlContentVerticalAlignment控制的是UIButtonimagetitle在竖直方向的对齐方式,其值有topbottomcenterfill。当指定为fill时,图片会在竖直方向被拉伸填满UIButton的高度。

    为了效果明显,我给上面的那个按钮设置了一个较大的宽高,当取各种值时,效果如下:

    ButtonEdgeInsets-Vertical.jpg

    的对齐方式。其值有leftrightcenterfill。当指定为fill时,图片并没有在水平方向将UIButton充满,而是在右侧留出了一定距离,这个距离应该是title的宽度,但是title实际上也没有乖乖的跑到那段空隙去,而是和image重叠了╮(╯▽╰)╭

    当取各种值时,效果如下:

    ButtonEdgeInsets-Horizontal.jpg
    UIControlContentHorizontalAlignment控制的则是水平方向

    UIEdgeInsets

    UIButton共有3个与UIEdgeInsets相关的属性:

    imageEdgeInsets调整image的上下左右边缘离开原来位置的距离,该调整并不会改变UIButton原来的大小,image为了适应调整,可能会变形或者跑出UIButton的外面。

    titleEdgeInsets调整title的上下左右边缘离开原来位置的距离,该调整并不会改变UIButton原来的大小,title为了适应调整,文字可能显示不全或者跑出UIButton的外面。

    contentEdgeInsets调整UIButton本身的上下左右边缘离开原来位置的距离,该调整会改变UIButton的大小。

    这个3个属性的默认值都是.zero

    UIEdgeInsetstopleftbottomright构成,对于imageEdgeInsetstitleEdgeInsets来说:

    top为正值时,控件会相对原来所在的位置下移相应值,控件的顶部边缘会在原来位置的下方相应值。top为负值时,控件会相对原来的位置上移相应值,控件的顶部边缘会在原来位置的上方相应值。

    left为正值时,控件会相对原来所在的位置右移相应值,控件的左侧边缘会在原来位置的右方相应值。left为负值时,控件会相对原来的位置左移相应值,控件的左侧边缘会在原来位置的左方相应值。

    bottom为正值时,控件会相对原来所在的位置上移相应值,控件的底部边缘会在原来位置的上方相应值。bottom为负值时,控件会相对原来的位置下移相应值,控件的底部边缘会在原来位置的下方相应值。

    right为正值时,控件会相对原来所在的位置左移相应值,控件的右侧边缘会在原来位置的左方相应值。right为负值时,控件会相对原来位置右移相应值,控件的右侧边缘会在原来位置的右方相应值。

    对于contentEdgeInsets来说,当topleftbottomright为正值时,会使UIButton向四周扩展变大。为负值时,会使UIButton向内收缩变小。哈哈,这样好记一些😄

    现在把UIButton的固定大小去掉,让它自己自适应。先来一个水平方向调整的:

    yellowButton.contentHorizontalAlignment = .left
    yellowButton.contentVerticalAlignment = .center
    yellowButton.imageEdgeInsets = UIEdgeInsetsMake(0, 20, 0, 0)
    yellowButton.titleEdgeInsets = UIEdgeInsetsMake(0, 20, 0, 0)
    
    ButtonEdgeInsets-Left.jpg
    第一张图只设置了imageEdgeInsets,没有设置titleEdgeInsets,第三张两者都设置了。可以看到,imageEdgeInsetstitleEdgeInsets并不会互相影响,第一张图中imagetitle重合了,并没有把title往右挤了相应距离。第二张和第四张看到,imagetitle本身被压缩了。

    还有一点值得注意的是,如果原来UIButton的大小能容纳下调整后的imagetitle,它们将不会被压缩。像第一张那样,image左移后还是放得下的,所以没有被压缩,title却放不下了,所以被压缩了。为什么说是原来的大小呢,因为调整contentEdgeInsets也会使UIButton变大,但是imagetitle却不会因此而不被压缩。再来一个竖直方向调整的:

    yellowButton.contentHorizontalAlignment = .center
    yellowButton.contentVerticalAlignment = .top
    yellowButton.imageEdgeInsets = UIEdgeInsetsMake(20, 0, 0, 0)
    yellowButton.titleEdgeInsets = UIEdgeInsetsMake(20, 0, 0, 0)
    
    ButtonEdgeInsets-Top.jpg
    第一张图仍然是只调整了imageEdgeInsets的效果。

    从上面的结果可以看到调整imageEdgeInsetstitleEdgeInsets并不会改变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)
    
    ButtonEdgeInsets-Content.jpg
    好吧,结果并不如我们想象的一样,UIButton是变大了,但是image
    title并没有自己调整,还是一个压缩的状态。验证了上面值得注意的那一点~ 这时候要再调整一下它们的right值了,将其设置为-20
    ,如愿得到了下面的结果。 ButtonEdgeInsets-Content-Right.jpg

    需要注意 当设置contentHorizontalAlignment.left时,再设置imageEdgeInsetstitleEdgeInsets.right为负值时,如果imagetitle原来是压缩状态,会对其调整。如果原来是正常状态,则不会产任何影响。也就是说,imageEdgeInsetstitleEdgeInsets的设置并不会让imagetitle被拉伸!其他方向亦如此~所以,为了保证imagetitle始终不被压缩,.left设置了多少正值,.right就设置多少负值。上下方向也一样。

    实战

    上面做了这么多铺垫,现在通过设置UIButton的3个EdgeInsets属性来实现一些我们想要的效果吧😉

    在做水平方向的调整时,最好将contentHorizontalAlignment设置为.left,这样改动就从左开始。在做竖直方向的调整时,最好将contentVerticalAlignment设置为.top,这样改动就从上面开始。对于自己在设置时,比较容易在脑子想象每个值设置完的样子😁

    例1:设置一个四周间隔20,image和title之间间隔20的button。

    计算过程如下:

    ButtonEdgeInsets-Space.jpg
    //向的调整,设为靠左对齐
    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)
    

    最后,完美😂

    ButtonEdgeInsets-Space-Result.jpg
    例2:设置一个image在上居中,title在下居中,两者之间间距20,四周间距20的button。

    这个看起来复杂一些,但也只是计算复杂一些~ 计算过程如下,求出标记问号的距离就行了:

    ButtonEdgeInsets-Center.jpg
    //设置水平和竖直的对齐方式
    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)
    

    运行后的结果:

    ButtonEdgeInsets-Center-Result.jpg

    了解imageEdgeInsetstitleEdgeInsetscontentEdgeInsets后,就可以随心所欲的来设置自己的button了。

    至此,总结完毕😆

    –End–

    文章来源于意林的bolg的技术博客,意林授权
    传送门:http://shinancao.github.io/2016/12/15/iOS-UIButton-EdgeInsets/

    相关文章

      网友评论

          本文标题:理解UIButton的各种EdgeInsets

          本文链接:https://www.haomeiwen.com/subject/advtvttx.html