自定义控件之调整按钮中子控件(图片和文字)的位置

其实还有一种是在storyBoard中实现的,只需要设置对应空间的左右间距:

这里实现前面两种自定义的方式

一:imageRectForContentRect/titleRectForContentRect

自定义一个按钮控件在系统自带的位置设置方法中实现对应子控件位置调整

 /**

  *  设置内部图标的frame

  */

 - (CGRect)imageRectForContentRect:(CGRect)contentRect

 {

     CGFloat imageY = ;

     CGFloat imageW = self.height;

     CGFloat imageH = imageW;

     CGFloat imageX = self.width - imageW;

     return CGRectMake(imageX, imageY, imageW, imageH);

 }

 /**

  *  设置内部文字的frame

  */

 - (CGRect)titleRectForContentRect:(CGRect)contentRect

 {

     CGFloat titleY = ;

     CGFloat titleX = ;

     CGFloat titleH = self.height;

     CGFloat titleW = self.width - self.height;

     return CGRectMake(titleX, titleY, titleW, titleH);

 }

然后做进步一的优化:

 - (id)initWithFrame:(CGRect)frame

 {

     self = [super initWithFrame:frame];

     if (self) {

         // 内部图标居中

         self.imageView.contentMode = UIViewContentModeCenter;

         // 文字对齐

         self.titleLabel.textAlignment = NSTextAlignmentRight;

         // 文字颜色

         [self setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];

         // 字体

         self.titleLabel.font = HMNavigationTitleFont;

         // 高亮的时候不需要调整内部的图片为灰色

         self.adjustsImageWhenHighlighted = NO;

     }

     return self;

 }

 - (void)setTitle:(NSString *)title forState:(UIControlState)state

 {

     [super setTitle:title forState:state];

     // 1.计算文字的尺寸

     CGSize titleSize = [title sizeWithFont:self.titleLabel.font];

     // 2.计算按钮的宽度

     self.width = titleSize.width + self.height + ;

 }

二:类似签名的自定义View在layoutSubViews里面实现子控件位置的调整:

创建一个继承自UIButton得子类,实现响应的自定义子控件的方法

 - (id)initWithFrame:(CGRect)frame

 {

     self = [super initWithFrame:frame];

     if (self) {

         //设置文字颜色

         [self setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];

         //设置文字大小

         self.titleLabel.font = [UIFont boldSystemFontOfSize:];

         //设置按钮的图片(普通和选中)

         [self setImage:[UIImage imageNamed:@"navigationbar_arrow_down"] forState:UIControlStateNormal];

         [self setImage:[UIImage imageNamed:@"navigationbar_arrow_up"] forState:UIControlStateSelected];

     }

     return self;

 }

 - (void)layoutSubviews

 {

     [super layoutSubviews];

     // 如果仅仅是调整按钮内部titleLabel和imageView的位置,那么在layoutSubviews中单独设置位置即可

     // 1.计算titleLabel的frame

     self.titleLabel.x = self.imageView.x - ;

     // 2.计算imageView的frame

     self.imageView.x = CGRectGetMaxX(self.titleLabel.frame);

 }

 - (void)setTitle:(NSString *)title forState:(UIControlState)state

 {

     [super setTitle:title forState:state];

     // 只要修改了文字,就让按钮重新计算自己的尺寸

     [self sizeToFit];

 }

 - (void)setImage:(UIImage *)image forState:(UIControlState)state

 {

     [super setImage:image forState:state];

     // 只要修改了图片,就让按钮重新计算自己的尺寸

     [self sizeToFit];

 }

最后来看看Swift怎么去实现:

 class ShopButton: UIButton {

     var shop: Shop? {

         didSet {

             print(shop)

             // 重写set方法

             /*

             // 错误写法

             self.imageView?.image = UIImage(named: shop!.icon)

             self.titleLabel?.text = shop!.name

             */

             self.setTitle(shop!.name, forState: UIControlState.Normal)

             self.setImage(UIImage(named: shop!.icon), forState: UIControlState.Normal)

         }

     }

     class func shopView(shop: Shop) -> ShopButton{

         let btn:ShopButton = ShopButton()

         btn.shop = shop

         return btn

     }

     /*

     override func titleRectForContentRect(contentRect: CGRect) -> CGRect {

         return CGRectMake(0, contentRect.size.width, contentRect.size.width, contentRect.size.height - contentRect.size.width)

     }

     override func imageRectForContentRect(contentRect: CGRect) -> CGRect {

         return CGRectMake(0, 0, contentRect.size.width, contentRect.size.width)

     }

     */

     override func layoutSubviews() {

         super.layoutSubviews()

         print(self.frame)

         let width: CGFloat = self.frame.size.width

         let height: CGFloat = self.frame.size.height

         self.imageView?.frame = CGRectMake(, , width, width)

         self.titleLabel?.frame = CGRectMake(, width, width, height - width)

     }

 }

其实思路非常简单,就是设置对应控件的frame就可以,当然如果真的不想写那么就直接使用吧,使用方法有两种直接创建设置对应的子控件需要的值或者在XIB或StoryBoard中给对应的UIButton控件设置为我们自定义的类就可以。

iOS开发——UI高级OC篇&自定义控件之调整按钮中子控件(图片和文字)的位置的更多相关文章

  1. iOS开发——UI精选OC篇&UIApplication,UIWindow,UIViewController,UIView(layer)简单介绍

    UIApplication,UIWindow,UIViewController,UIView(layer)简单介绍 一:UIApplication:单例(关于单例后面的文章中会详细介绍,你现在只要知道 ...

  2. iOS开发——项目实战OC篇&类QQ黏性按钮(封装)

    类QQ粘性按钮(封装) 那个,先来说说原理吧: 这里原理就是,在界面设置两个控件一个按钮在上面,一个View在下面(同样大小),当我们拖动按钮的时候显示下面的View,view不移动,但是会根据按钮中 ...

  3. Qt编写自定义控件8-动画按钮组控件

    前言 动画按钮组控件可以用来当做各种漂亮的导航条用,既可以设置成顶部底部+左侧右侧,还自带精美的滑动效果,还可以设置悬停滑动等各种颜色,原创作者雨田哥(QQ:3246214072),驰骋Qt控件界多年 ...

  4. iOS开发——网络实用技术OC篇&网络爬虫-使用青花瓷抓取网络数据

    网络爬虫-使用青花瓷抓取网络数据 由于最近在研究网络爬虫相关技术,刚好看到一篇的的搬了过来! 望谅解..... 写本文的契机主要是前段时间有次用青花瓷抓包有一步忘了,在网上查了半天也没找到写的完整的教 ...

  5. ios开发——实用技术篇OC篇&iOS的主要框架

    iOS的主要框架         阅读目录 Foundation框架为所有的应用程序提供基本系统服务 UIKit框架提供创建基于触摸用户界面的类 Core Data框架管着理应用程序数据模型 Core ...

  6. iOS开发——运行时OC篇&使用运行时获取系统的属性:使用自己的手势修改系统自带的手势

    使用运行时获取系统的属性:使用自己的手势修改系统自带的手势 有的时候我需要实现一个功能,但是没有想到很好的方法或者想到了方法只是那个方法实现起来太麻烦,一或者确实为了装逼,我们就会想到iOS开发中最牛 ...

  7. iOS开发——网络实用技术OC篇&网络爬虫-使用java语言抓取网络数据

    网络爬虫-使用java语言抓取网络数据 前提:熟悉java语法(能看懂就行) 准备阶段:从网页中获取html代码 实战阶段:将对应的html代码使用java语言解析出来,最后保存到plist文件 上一 ...

  8. iOS开发——实战总结OC篇&网易彩票开发知识点总结

    网易彩票开发知识点总结 关于网易彩票开发中遇到了不少的坑,弄了好久才弄懂,或者有些犹豫很久没用就不记得了,所以这里就总结了一下,希望以后不会忘记,就算忘记也能快速查看! /************** ...

  9. 【iOS开发-56】案例BUG:button的enabled、控件的userInteractionEnabled以及两种提示框UIAlert和UIActionSheet

    接上述案例找BUG:[iOS开发-51]案例学习:动画新写法.删除子视图.视图顺序.延迟方法.button多功能使用方法及icon图标和启动页设置 (1)BUG:答案满了就不能再点击optionbut ...

随机推荐

  1. 爬虫技术之——bloom filter(含java代码)

    在爬虫系统中,在内存中维护着两个关于URL的队列,ToDo队列和Visited队列,ToDo队列存放的是爬虫从已经爬取的网页中解析出来的即将爬取的URL,但是网页是互联的,很可能解析出来的URL是已经 ...

  2. [转]32位和64位系统区别及int字节数

    一)64位系统和32位有什么区别? 1.64bit CPU拥有更大的寻址能力,最大支持到16GB内存,而32bit只支持4G内存 2.64位CPU一次可提取64位数据,比32位提高了一倍,理论上性能会 ...

  3. android开发中遇到的bug

    这种NullPointerException这么解决啊 Activity.dispatchTouchEvent 里try catch一下 参考:http://www.eoeandroid.com/th ...

  4. navicat 或者workbench 无法连接127.0.0.1(61)的解决方法

    1.输入mysql -uroot 进入命令行模式, 2.输入"show variables like '%sock%';"查看sock文件所在位置 如: 3.配置客户端(以navi ...

  5. LeetCode(8) - String to Integer (atoi)

    虽然是easy,却是比较繁琐的一道题,需要考虑各种边界条件.在WA了好几遍之后,才把各种边界条件给补全.需要考虑到的因素如下: 输入不合法字符,非"0-9",对于首位,合法字符还包 ...

  6. 应用删除后 Launchpad 上仍有应用图标无法删除的解决方法

    应用删除后 Launchpad 上仍有应用图标上带有问号且无法删除时,可以将 launchpad 重置. 在终端输入: defaults write com.apple.dock ResetLaunc ...

  7. HDU ACM 1325 / POJ 1308 Is It A Tree?

    Is It A Tree? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tot ...

  8. linux中ctrl+z和ctrl+c的区别

    ctrl+c和ctrl+z都是中断命令,但是他们的作用却不一样.ctrl+c是强制中断程序的执行,而ctrl+z的是将任务中断,但是此任务并没有结束,他仍然在进程中他只是维持挂起的状态,用户可以使用f ...

  9. XE8 hash

    c++builder  xe8 hash calc md5.sha256.sha384.sha512 file and string sha256.sha384.sha512  must call l ...

  10. Multimedia&Network

    [Multimedia&Network] 1.Unity3D共支持4种格式音乐文件: 2.AudioSource用于指明音频源,被绑定在一个GameObject身上.光有AudioSource ...