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

其实还有一种是在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. os和os.path模块

    Os和os.path模块函数 1.      Os模块 函数 描述 文件处理 Mkfifo()/mknod() 创建命名管道/创建文件系统节点 Remove()/unlink() 删除文件 Renam ...

  2. nagios监控linux设置

    本章主要用来设置nagios的相关配置文件,从而能实现对linux系统的监控. 在进行监控相关服务的时候,nagios会周期性的调用插件去监测服务器的状态,nagios自带的所有插件都放在如下目录: ...

  3. 数往知来C#之接口 值类型与引用类型 静态非静态 异常处理 GC垃圾回收 值类型引用类型内存分配<四>

    C# 基础接口篇 一.多态复习 使用个new来实现,使用virtual与override    -->new隐藏父类方法 根据当前类型,电泳对应的方法(成员)    -->override ...

  4. 一个相当好的状态机(DFA, 确定有限状态机)的编码实现,相当简洁漂亮

    从jsoup而来,文章见: https://github.com/code4craft/jsoup-learning/blob/master/blogs/jsoup4.md 状态机 Jsoup的词法分 ...

  5. E2202 Required package 'VclJPG' not found

    xe8 [dcc32 Fatal Error] RaizeComponentsVcl_Design.dpk(40): E2202 Required package 'VclJPG' not found ...

  6. HDU 4619 Warm up 2(2013多校2 1009 二分匹配)

    Warm up 2 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total S ...

  7. pyqt中QDateTimeEdit/QDateEdit相关使用方法

    QDateTimeEdit/QDateEdit clear (self)QDate date (self)QDateTime dateTime (self)setDate (self, QDate d ...

  8. HDU2947Bicycle Puzzle(组合原理)

    题目大意: 你和朋友两人玩游戏,将一个图片均等切割成W* H块,打乱每一小块的位置.拼图游戏开始.每次,可以交换任意两块,记下交换的次数,图片还原游戏结束.得分为执行交换的次数.得分越小越好. 现在, ...

  9. Spring REST实践之安全

    Securing REST Services 一般有六种方式实现的REST服务的安全: Session-based security HTTP Basic Authentication Digest ...

  10. android 三种弹出框之一PopupWindow

    PopupWindow 在android的弹出框我目前了解到的是有三种:AlertDialog,PopupWindow,Activity伪弹框, AlertDialog太熟悉了,这里就不介绍了 就先看 ...