级别: ★☆☆☆☆
标签:「iOS」「UIButton」「自动布局」
作者: 沐灵洛
审校: QiShare团队


UIButton是开发过程中最常用的控件,可以设置各种样式,也可以自定义添加图片、标题。

但是,实际设计中往往与上图的默认样式不一致。比如图片和文字间距为10,图片距离左边的间距为10,标题距离右边为10,这就需要我们使用一些方法来实现效果。

1. 使用imageEdgeInsets和titleEdgeInsets
btn.imageEdgeInsets = UIEdgeInsetsMake(0, 10, 0, 0);
btn.titleEdgeInsets = UIEdgeInsetsMake(0, 20, 0, 10);
复制代码

上述方式可以实现需求效果,但由于特殊的计算方式,使得代码不太直观。具体内容可参考文章 iOS UIButton之UIEdgeInsets详解

2.渲染时给出imageView和titleLabel的frame

重写以下两个方法,返回需要的frame,使imageView和titleLabel分开渲染。

  • -(CGRect)titleRectForContentRect:(CGRect)contentRect;
  • -(CGRect)imageRectForContentRect:(CGRect)contentRect;

所以我们创建一个QiShareButton继承自UIButton,并定义两个属性

@interface QiShareButton : UIButton@property (nonatomic, assign) CGRect imageRect;
@property (nonatomic, assign) CGRect titleRect;@end
复制代码

在.m中重写两个方法

- (CGRect)titleRectForContentRect:(CGRect)contentRect {if (!CGRectIsEmpty(self.titleRect) && !CGRectEqualToRect(self.titleRect, CGRectZero)) {return self.titleRect;} else {return [super titleRectForContentRect:contentRect];}
}- (CGRect)imageRectForContentRect:(CGRect)contentRect {if (!CGRectIsEmpty(self.imageRect)&&!CGRectEqualToRect(self.imageRect, CGRectZero)) {return self.imageRect;} else {return [super imageRectForContentRect:contentRect];}
}
复制代码

关于使用:

QiShareButton *btn = [[QiShareButton alloc]initWithFrame:CGRectZero];
btn.backgroundColor = [UIColor cyanColor];
[btn addTarget:self action:@selector(test) forControlEvents:UIControlEventTouchUpInside];
[btn setTitle:@"QiShareBtn" forState:UIControlStateNormal];
[btn setImage:[UIImage imageNamed:@"icon_presonal_sign"] forState:UIControlStateNormal];
btn.titleRect = CGRectMake(60.0 , 10.0, 100.0, 40.0);
btn.imageRect = CGRectMake(10.0, 10.0, 40.0, 40.0);
[self.view addSubview:btn];
复制代码

在上述代码中,以CGRectZero初始化button,然后分别设置titleRect和imageRect属性,观察到虽然imageView和titleLabel正常绘制,但是button的frame依然是Zero,在橙色的大背景下看不到青色(cyanColor)的button。

我们设置button的frame不足以显示imageView和titleLabel

QiShareButton *btn =  [[QiShareButton alloc] initWithFrame:CGRectMake(100.0, 100.0, 20.0, 20.0)];
复制代码

我们希望button能够根据titleRect和imageRect属性的值自动适配合适的frame。即:设置titleRect和imageRect便可以算出button的大小。 所以重写UIButton的layoutSubViews方法:

- (void)layoutSubviews {[super layoutSubviews];BOOL hasSetTitleRect = !(CGRectIsEmpty(self.titleRect) || CGRectEqualToRect(self.titleRect, CGRectZero));BOOL hasSetImageRect = !(CGRectIsEmpty(self.imageRect) || CGRectEqualToRect(self.imageRect, CGRectZero));if (hasSetImageRect || hasSetTitleRect) {CGRect rect = self.frame;CGRect curentRect =  CGRectUnion(hasSetImageRect ? self.imageRect : CGRectZero, hasSetTitleRect  ? self.titleRect : CGRectZero);rect.size.width = curentRect.size.width + curentRect.origin.x * 2;rect.size.height = curentRect.size.height + curentRect.origin.y * 2;self.frame = rect;}}
复制代码

使用效果(未给定button的frame或者宽高不正确)

btn.titleRect = CGRectMake(60.0 , 10.0, 100.0, 40.0);
btn.imageRect = CGRectMake(10.0, 10.0, 40.0, 40.0);
复制代码
btn.imageRect = CGRectMake(110.0 , 10.0, 40.0, 40.0);
btn.titleRect = CGRectMake(10.0, 10.0, 100.0, 40.0);
复制代码
btn.titleRect = CGRectMake(10.0 , 10.0, 100, 40);
btn.imageRect = CGRectMake(40, 60, 40, 40);
复制代码
btn.titleRect = CGRectMake(10 , 60, 100, 40);
btn.imageRect = CGRectMake(40, 10, 40, 40);
复制代码

源码:Demo源码


小编微信:可加并拉入《QiShare技术交流群》。

关注我们的途径有:
QiShare(简书)
QiShare(掘金)
QiShare(知乎)
QiShare(GitHub)
QiShare(CocoaChina)
QiShare(StackOverflow)
QiShare(微信公众号)

推荐文章:
iOS 指定初始化方法
UIView中的hitTest方法
iOS关于tabBar的几处笔记
A的女儿是B的女儿的妈妈,A是B的谁?
算法小专栏:选择排序
iOS Runloop(一)
奇舞周刊

转载于:https://juejin.im/post/5cdd2e8fe51d45475b17e3b4

iOS UIButton根据内容自动布局相关推荐

  1. iOS - UIButton 开发总结

    iOS - UIButton 开发总结 一 UIButton基础     iOS中提供了UIButton.UILable.UITextField.UIImageView等基础UI控件,继承于UIVie ...

  2. ios怎么引入masonry_iOS自动布局——Masonry详解

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 作者:oceanlong | 腾讯 移动客户端开发工程师 前言 UI布局是整个前端体系里不可或缺的一环.代码的布局是设计语言与用户视觉感受沟 ...

  3. iOS UIButton 图片文字上下垂直布局 解决方案

    iOS UIButton 图片文字上下垂直布局 解决方案 参考文章: (1)iOS UIButton 图片文字上下垂直布局 解决方案 (2)https://www.cnblogs.com/yajunL ...

  4. iOS UIButton文字和图片间距随意调整

    代码地址如下: http://www.demodashi.com/demo/11606.html 前记 在开发中,我们经常会遇到这么一种情况,就是一个按钮上面有图片也有文字,但是往往设计并不是我们想要 ...

  5. 关于xcode7下的ios模拟器输入内容无法显示系统键盘的解决办法

    xcode7下的ios模拟器输入内容无法系统键盘,只能用电脑键盘输入内容,这样可能会对调试带来麻烦. 其实xcode7下的ios模拟器默认只能使用一种,要么是模拟器系统键盘,要么就是是电脑键盘.设置方 ...

  6. oc调用python_引用ios-和引用ios相关的内容-阿里云开发者社区

    iOS内存管理机制解析之MRC手动引用计数机制 前言: iOS的内存管理机制ARC和MRC是程序员参加面试基本必问的问题,也是考察一个iOS基本功是 否扎实的关键,这样深入理解内存管理机制的重要性就不 ...

  7. ios调用python_引用ios-和引用ios相关的内容-阿里云开发者社区

    iOS内存管理机制解析之MRC手动引用计数机制 前言: iOS的内存管理机制ARC和MRC是程序员参加面试基本必问的问题,也是考察一个iOS基本功是 否扎实的关键,这样深入理解内存管理机制的重要性就不 ...

  8. iOS UIButton(按钮)

    UIButton属性 1.UIButton状态: UIControlStateNormal // 正常状态 UIControlStateHighlighted // 高亮状态 UIControlSta ...

  9. IOS UILabel 根据内容自适应高度

    iOS Label 自适应高度  适配iOS7以后的版本 更多 self.contentLabelView = [[UILabel alloc] init]; self.contentLabelVie ...

最新文章

  1. 正则表达式口诀及教程(推荐)
  2. Linux中的umask
  3. iOS - OC iOS 开发体系
  4. 大数据技术:Zookeeper分布式协调服务
  5. table control的修改/排序/删除功能实现实例
  6. LoRa 之一 旧版驱动(sx12xxDrivers-V2.1.0)移植及驱动架构详解
  7. Python合并字典的七种方式!
  8. Bug测试报告--食物链教学工具--奋斗吧兄弟
  9. webservice 实现与his系统对接_[Share] EDI 及其他常见系统对接技术
  10. Visual C++ 基础数据类型的转换
  11. xshell6左侧导航显示_【iOS12人机交互指南】7.1-导航栏
  12. 2021年中国一次性医用传感器市场趋势报告、技术动态创新及2027年市场预测
  13. JXTA.pdf及其源代码、Practical JXTA II
  14. SCM供应链管理系统解决方案:助力企业采购流程高效运行,全面降低供应链风险
  15. 一文带你走进网络编程
  16. html模块 码工助手,码工助手在线布局使用注意事项
  17. 大白话5分钟带你走进人工智能-第33节神经网络和神经元概念(1)
  18. WEB应用图片的格式,以及各自的特点和优化(一) by FungLeo
  19. 智能机器人与智能系统(大连理工大学庄严教授)——3.工业机器人
  20. 改注册表让win7/win8中的控制面板项的名字随心所欲

热门文章

  1. ajax 实时进度_如何做好项目进度管理?
  2. android之http协议编程(源码ppt),Android网络编程(八)源码解析OkHttp中篇[复用连接池]...
  3. Linux常用编辑器使用:vi、vim、nano、gedit
  4. php连接mysqli面向过程,PHP基础知识总结:MySQLi 面向过程
  5. 获取授时时间_gps时间同步服务器在通信行业的解决方案
  6. 初探百度大数据分析挖掘平台Jarvis
  7. 暖通lisp快捷键_CAD 快捷键一览
  8. 天翼云从业认证课后习题(3.2天翼云存储产品和3.4云数据库)
  9. 百练OJ:2964:日历问题
  10. 【项目管理】质量管理