button可以设置 titleEdgeInsets属性和 imageEdgeInsets属性来调整其image和label相对位置,具体参考http://stackoverflow.com/questions/4564621/aligning-text-and-image-on-uibutton-with-imageedgeinsets-and-titleedgeinsets/5358259#5358259的第二个答案,关键是这个:
 
这里说说我自己的理解,理解有误的地方,大家可以讨论
 
前提:这是在button的frame足够显示image和label内容的情况下,如果frame不够,图片或者文字会被压缩(demo的button是xib上画的,所以大小刚刚好
2016.4.1更新:在xib或者storyboard上画的button,如果勾选了autolayout而不设置任何约束的话,系统会自动给button加上约束,
而且加上的约束是根据其在xib上的frame加的,这个约束会导致你重新设置title或者image button的大小也不会变;
所以建议还是提前设置好约束,对于button或者label来说,因为有intrinsicSize的存在,所以可以不设置宽高,只设置相对于其他空间的位置)
 
前置知识点:titleEdgeInsets是title相对于其上下左右的inset,跟tableView的contentInset是类似的,
如果只有title,那它上下左右都是相对于button的,image也是一样;
如果同时有image和label,那这时候image的上左下是相对于button,右边是相对于label的;title的上右下是相对于button,左边是相对于image的。
 
我写了个demo来说明怎么设置这两个属性以达到自己想要的效果:https://github.com/Phelthas/Demo_ButtonImageTitleEdgeInsets
看效果图来说明一下:
其中,右边的是给对应的左边的button及button.imageView, button.titleLabel加上边框的效果
 
默认情况下,button的image和label是紧贴着居中的,
那如果想要image在右边,label在左边应该怎么办呢?
答案就是:
self.oneButton.imageEdgeInsets = UIEdgeInsetsMake(0, labelWidth, 0, -labelWidth);
self.oneButton.titleEdgeInsets = UIEdgeInsetsMake(0, -imageWith, 0, imageWith);
来解释一下为什么:
其实就是这一句:This property is used only for positioning the image during layout
其实titleEdgeInsets属性和 imageEdgeInsets属性只是在画这个button出来的时候用来调整image和label位置的属性,并不影响button本身的大小(这个看第三排的图比较明显),
它们只是image和button相较于原来位置的偏移量,那什么是原来的位置呢?就是这个没有设置edgeInset时候的位置了。
 
如要要image在右边,label在左边,那image的左边相对于button的左边右移了labelWidth的距离,image的右边相对于label的左边右移了labelWidth的距离
所以,self.oneButton.imageEdgeInsets = UIEdgeInsetsMake(0, labelWidth, 0, -labelWidth);为什么是负值呢?因为这是contentInset,是偏移量,不是距离
同样的,label的右边相对于button的右边左移了imageWith的距离,label的左边相对于image的右边左移了imageWith的距离
所以self.oneButton.titleEdgeInsets = UIEdgeInsetsMake(0, -imageWith, 0, imageWith);
这样就完成image在右边,label在左边的效果了。
 
 
第三排,image在上,label在下
同样的第三排调整前的还是第一排的样子,
跟第一排比起来,image的中心位置向右移动了 CGFloat imageOffsetX = (imageWith + labelWidth) / 2 - imageWith / 2;
上向上移动了 CGFloat imageOffsetY = imageHeight / 2;
所以self.twoButton.imageEdgeInsets = UIEdgeInsetsMake(-imageOffsetY, imageOffsetX, imageOffsetY, -imageOffsetX);
label的中心位置像左移动了CGFloat labelOffsetX = (imageWith + labelWidth / 2) - (imageWith + labelWidth) / 2;
向下移动了CGFloat labelOffsetY = labelHeight / 2;
所以self.twoButton.titleEdgeInsets = UIEdgeInsetsMake(labelOffsetY, -labelOffsetX, -labelOffsetY, labelOffsetX);
然后就大功告成了,现在已经完美实现一个button内image在上,label在下,且居中了
 

2016.4.1更新
根据stackoverflow 上的解释,加入contentInset的考虑,可以很好的解决intrinsicSize的问题,效果如图:
其中约束是:
左边一列左对齐,上下间隔25
中间一列居中对齐,上下间隔25
右边一列右对齐,上下间隔25
全部不设置宽高,用button的intrinsicSize来确定大小
 
左边一列和中间一列是只设置了titleEdgeInsets属性和imageEdgeInsets的效果;
右边一列是追加了contentInset的效果;
 
button的可主控范围是绿色框框内的部分,在模拟器上可以试试,点击不在绿色框框内的部分button是不会有响应的。
为什么呢?还是文章最上面的那句,titleEdgeInsets属性和imageEdgeInsets只是用来设置title和image的位置,但是系统不会用它们来计算button的intrinsicSize;
button是用contentInset来计算其intrinsicSize的大小的!!!
所以右边一列是更好的,可以比完美的配合autoLayout;
 
另:这个用button自身属性来实现图片文字自由排列的方法已经封装成一个分类,而且已经支持cocoaPods了
只需要一行代码,就可以实现右边一列的效果:
[self.twoButton_line setImagePosition:LXMImagePositionTop spacing:10];
欢迎使用~~ 
 

UIButton的titleEdgeInsets属性和imageEdgeInsets属性实现图片文字按要求排列的更多相关文章

  1. iOS - UIButton设置图片文字上图下文排列

    经查阅资料及尝试,最终解决了在图片和文字垂直排列的情况下,如果文字长度变化会导致图片位置变动的问题,最开始采用了网上比较多的做法,做法如下: @interface UIButton (UIButton ...

  2. UIButton的titleEdgeInsets和imageEdgeInsets属性

    转:http://www.cnblogs.com/huichun/p/3419596.html uiButton控件上自带了一个uiLabel类型的子控件和一个uiImageView类型的子控件,如果 ...

  3. UIButton中的三个UIEdgeInsets属性

    接着昨天的 UIButton中的三个UIEdgeInsets属性 ,今天我们具体谈谈UIButton的contentEdgeInsets.titleEdgeInsets.imageEdgeInsets ...

  4. APUE学习之多线程编程(三):线程属性、同步属性

    一.线程属性      可以使用pthread_attr_t结构修改线程默认属性,并这些属性和创建的线程练习起来,可以使用pthread_att_init函数初始化pthread_attr_t结构,调 ...

  5. jquery html属性和text属性的区别

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  6. 【Python】[面性对象编程] 获取对象信息,实例属性和类属性

    获取对象信息1.使用isinstance()判断class类型2.dir() 返回一个对象的所有属性和方法3.如果试图获取不存在的对象会抛出异常[AttributeError]4.正确利用对象内置函数 ...

  7. Struts2 配置文件result的name属性和type属性

    Struts2 配置文件result的name属性和type属性:Name属性SUCCESS:Action正确的执行完成,返回相应的视图,success是 name属性的默认值: NONE:表示Act ...

  8. _.属性和self.属性,我遇到的那些坑

    只怪当时_.属性和self.属性当时没有研究透,所以为自己掉入坑里埋下了伏笔.下面从我的坑开始说起: 我写了个懒加载,重写了一个数组属性的get方法,在get方法里面创建了一个数组来获取数据,那么调用 ...

  9. 深入理解css中position属性及z-index属性

    深入理解css中position属性及z-index属性 在网页设计中,position属性的使用是非常重要的.有时如果不能认识清楚这个属性,将会给我们带来很多意想不到的困难. position属性共 ...

随机推荐

  1. [java] 汇率换算器实现-插曲1-正则表达式(1)

    [java] 汇率换算器实现-插曲1-正则表达式(1) // */ // ]]> // */ // ]]>   [java] 汇率换算器实现-插曲1-正则表达式(1) Table of C ...

  2. Dripicons – 精美的扁平风格的免费矢量图标字体

    Dripicons 是一个好看的免费图标集,有超过 90 个扁平风格的图标,适用在 Web 应用程序中使用,如:箭头,媒体,图表等等. 集合多种矢量格式(PSD,AI,EPS,PDF,SVG),也可以 ...

  3. 使用Spark分析拉勾网招聘信息(四): 几个常用的脚本与图片分析结果

    概述 前一篇文章,已经介绍了BMR的基础用法,再结合Spark和Scala的文档,我想应该是可以开始你的数据分析之路的.这一篇文章,着重进行一些简单的思路上的引导和分析.如果你分析招聘数据时,卡在了某 ...

  4. MySQL5.7(5.6)GTID环境下恢复从库思(qi)路(yin)方(ji)法(qiao)

      要讨论如何恢复从库,我们得先来了解如下一些概念: GTID_EXECUTED:它是一组包含已经记录在二进制日志文件中的事务集合 GTID_PURGED:它是一组包含已经从二进制日志删除掉的事务集合 ...

  5. 安装windows系统的installutil

    /// 该服务必须在它可以执行之前安装.    /// 服务的安装和卸载“installutil.exe”“installutil.exe / U”的服务可执行文件作为最后一个参数.    ///  ...

  6. LeetCode - Triangle

    题目: Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjace ...

  7. Get sdcard directory by adb

    解决方案: adb shell echo $EXTERNAL_STORAGE  I am making an application, which pulls files(Saved by andro ...

  8. Sandcastle入门:创建C#帮助文档

    Sandcastle入门:创建C#帮助文档 今天学到了一个东西:利用vs2005生成的dll/xml来生成帮助文档. 完成这个伟大任务的是Sandcastle,微软推出的类库文档编译工具. 在开始这篇 ...

  9. ASP.NET入门教程:事件句柄

    事件句柄(event handler)是一种针对给定事件来执行代码的子例程. ASP.NET - 事件句柄 请看下面的代码: <% lbl1.Text="The date and ti ...

  10. 【C#进阶系列】13 接口

    C#不支持类的多继承,然而却可以继承多个接口.简单的就不说了,来看看下面的例子: public interface IRead { string GetText(); } public interfa ...