一、简介

由于父亲生病,好久没有更新博客了,今天10.1 国庆(应该说是昨天了,已经过了12点了),心血来潮自定义了一个小label。这个控件的难度并不大,也没有什么可以值得炫耀的技术点。写这个控件的主要原因是想再熟悉下label 和view 这连个最基本的控件。尽管天天接触这两个控件,但是我觉得很多初学者可能都并没有掌握这两个控件。废话不多说,先看一下效果图吧。

假装它可以闪动

二、思路

基本思路就是,先再初始化方法中创建所需要的控件,然后设置所需要的各种属性(注意各种属性之间可能会有先后顺序,但是使用者希望的是你给我提供的属性我可以随意顺序赋值,这也是我们需要解决的问题,实际上在大多数自定义控件中都会遇到这种问题),赋值完成之后进行各个控件的frame 设置,最后显示控件。下面先看一下头文件:

  1. //
  2. // DZLMoneyLabel.h
  3. // StandUI
  4. //
  5. // Created by 邓竹立 on 15/10/1.
  6. // Copyright (c) 2015年 GiveMeFive. All rights reserved.
  7. //
  8.  
  9. #import <UIKit/UIKit.h>
  10.  
  11. typedef NS_ENUM(NSInteger, DZLMoneyType) {
  12. DZLMoneyRMBNone,//啥也没有
  13. DZLMoneyRMBSymbol,//¥
  14. DZLMoneyRMBUnit,//元
  15. DZLMoneyDollarSymbol,//$
  16. };
  17.  
  18. @interface DZLMoneyLabel : UIView
  19.  
  20. @property(nonatomic,assign)CGFloat money;//金额
  21. @property(nonatomic,assign)NSInteger decimalPlace;//保留几位小数
  22. @property(nonatomic,assign)NSInteger integerPartFontSize;//整数部分的字体大小
  23. @property(nonatomic,assign)NSInteger decimalPartFontSize;//小数部分的字体大小
  24. @property(nonatomic,assign)DZLMoneyType moneyType;//金钱类型,美元什么的
  25. @property(nonatomic,assign)BOOL needCenterLine;//是否需要划线
  26.  
  27. @property(nonatomic,strong)NSArray *colors;//渐变色的颜色
  28. @property(nonatomic,assign)BOOL needTwinkleColors;//是否需要闪烁效果
  29.  
  30. - (instancetype)initWithFrame:(CGRect)frame __attribute__((unavailable("就不让你用! 你能咋地?"))) NS_DESIGNATED_INITIALIZER;
  31.  
  32. @end

头文件中所说的已经很清楚了,唯一要强调的就是最下面的代码,加上这段代码的可以堵住使用者的一些不当的初始化入口。比如说我只写了一个init 方法,懒得去处理initWithFrame方法,那么我就可以将这个方法堵住,使用者是收不到initWithFrame 的快捷提示的。这样的好处是可以减少使用者的疑惑,也可以减少我们的代码量,这个还不错吧?

三、代码解释

  1. -(instancetype)init
  2. {
  3. if (self=[super init])
  4. {
  5. UILabel *moneyLabel=[[UILabel alloc] init];
  6. self.moneyLabel=moneyLabel;
  7. [self addSubview:moneyLabel];
  8.  
  9. UIView *lineView=[[UIView alloc] init];
  10. self.lineView=lineView;
  11. [self addSubview:lineView];
  12.  
  13. //默认
  14. self.integerPartFontSize=13;
  15. self.decimalPartFontSize=10;
  16. self.moneyLabel.textColor=[UIColor orangeColor];
  17. self.moneyLabel.textAlignment=NSTextAlignmentCenter;
  18. self.lineView.backgroundColor=[UIColor orangeColor];
  19. self.lineView.hidden=YES;
  20. self.backgroundColor=[UIColor clearColor];
  21. }
  22. return self;
  23. }

在初始化方法里,我主要是进行控件的创建,我的习惯就是先把所需要的控件先创建了再说,frame 等到layoutSubViews 的时候再设置,而且是所有的子视图的frame都在layoutSubViews中设置,集中起来将来好管理。在初始化方法中,需要给使用者一些必要的默认值。

下面是属性设置部分的代码:

  1. -(void)setNeedCenterLine:(BOOL)needCenterLine
  2. {
  3. _needCenterLine=needCenterLine;
  4. self.lineView.hidden=!_needCenterLine;
  5. self.money=_money;
  6. }
  7.  
  8. -(void)setDecimalPlace:(NSInteger)decimalPlace
  9. {
  10. _decimalPlace=decimalPlace;
  11. self.money=_money;
  12. }
  13.  
  14. -(void)setIntegerPartFontSize:(NSInteger)integerPartFontSize
  15. {
  16. _integerPartFontSize=integerPartFontSize;
  17. self.money=_money;
  18. }
  19.  
  20. -(void)setDecimalPartFontSize:(NSInteger)decimalPartFontSize
  21. {
  22. _decimalPartFontSize=decimalPartFontSize;
  23. self.money=_money;
  24. }
  25.  
  26. -(void)setColors:(NSArray *)colors
  27. {
  28. _colors=colors;
  29. [self setNeedsLayout];//设置标记
  30. [self layoutIfNeeded];//如果有标记立即调用
  31. }
  32.  
  33. -(void)setMoney:(CGFloat)money
  34. {
  35. _money=money;
  36. NSString *moneyStr=[self stringByPrecisionWithMoney:_money];//其实就是选择显示的精度
  37. moneyStr=[self addMoneyTypeWithString:moneyStr];//添加人民币符号等
  38.  
  39. NSMutableAttributedString *attrString=[[NSMutableAttributedString alloc] initWithString:moneyStr attributes:nil];
  40. NSRange range=[moneyStr rangeOfString:@"."];
  41.  
  42. NSString *integerPartStr;
  43. NSString *decimalPartStr;
  44. if (range.length>0)
  45. {
  46. integerPartStr=[moneyStr substringToIndex:range.location];
  47. decimalPartStr=[moneyStr substringFromIndex:range.location+1];
  48. NSRange integerPartRange=[moneyStr rangeOfString:integerPartStr];
  49. NSRange decimalPartRange=[moneyStr rangeOfString:decimalPartStr];
  50. [attrString addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"Helvetica" size:self.integerPartFontSize] range:integerPartRange];
  51. [attrString addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"Helvetica" size:self.decimalPartFontSize] range:decimalPartRange];
  52. }else
  53. {
  54. integerPartStr=moneyStr;
  55. decimalPartStr=@"";
  56. NSRange integerPartRange=[moneyStr rangeOfString:integerPartStr];
  57. [attrString addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"Helvetica" size:self.integerPartFontSize] range:integerPartRange];
  58. }
  59.  
  60. self.moneyLabel.attributedText=attrString;
  61. [self setColors:_colors];
  62. }
  63.  
  64. -(NSString*)stringByPrecisionWithMoney:(CGFloat)money
  65. {
  66. NSString *moneyStr;
  67. if (self.decimalPlace==0)
  68. {
  69. moneyStr=[NSString stringWithFormat:@"%.0f",money];
  70. }else if(self.decimalPlace==1)
  71. {
  72. moneyStr=[NSString stringWithFormat:@"%.1f",money];
  73. }else if (self.decimalPlace==2)
  74. {
  75. moneyStr=[NSString stringWithFormat:@"%.2f",money];
  76. }else
  77. {
  78. moneyStr=[NSString stringWithFormat:@"%g",money];
  79. }
  80. return moneyStr;
  81. }
  82.  
  83. -(NSString *)addMoneyTypeWithString:(NSString*)moneyStr
  84. {
  85. switch (self.moneyType)
  86. {
  87. case DZLMoneyRMBSymbol:
  88. {
  89. moneyStr=[@"¥" stringByAppendingString:moneyStr];
  90. }
  91. break;
  92.  
  93. case DZLMoneyRMBUnit:
  94. {
  95. moneyStr=[moneyStr stringByAppendingString:@"元"];
  96. }
  97. break;
  98.  
  99. case DZLMoneyDollarSymbol:
  100. {
  101. moneyStr=[@"$" stringByAppendingString:moneyStr];
  102. }
  103. break;
  104.  
  105. default:
  106. break;
  107. }
  108. return moneyStr;
  109. }

以上代码其实不用细看,其基本思路就是先设置精度、金钱类型等属性,然后再设置金额、最后设置渐变色。如果使用者不小心把顺序搞错了,那么我们就再手动帮他们把顺序纠正过来。比如再设置精度的方法内部调用设置金额的方法。这里再说一下layoutIfNeed 和 setNeedsLayout。 setNeedsLayout其实是做了一个标记:告诉系统某控件需要调用layoutSubViews 了,但是什么时候掉我不管。layoutIfNeed其实是一次检查:这个控件有没有刷新标记啊?有的话我立马调用layoutSubViews。置于layoutSubViews方法,那就没什么可说的了:

  1. -(void)layoutSubviews
  2. {
  3. [super layoutSubviews];
  4. [self.moneyLabel sizeToFit];
  5. self.bounds=CGRectMake(0, 0, self.moneyLabel.bounds.size.width, self.moneyLabel.bounds.size.height);
  6. self.moneyLabel.frame=self.bounds;
  7.  
  8. if (!self.needCenterLine)
  9. {
  10. return;
  11. }
  12. const CGFloat lineH=1.25;
  13. self.lineView.frame=CGRectMake(0,self.bounds.size.height*0.5 , self.bounds.size.width, lineH);
  14. }

其他的只要看代码里的注释就可以了,总的来说在写这段代码时候遇到挺多坑的,不过还是很有收获,对UIView 又加深了印象。最后说两句题外话:程序员需要不断地去学习。程序员需要向其他程序员学习。拜拜各位,睡觉喽~

  1. -(void)textColorChange
  2. {
  3. //颜色交替
  4. id lastColor=[self.randomColors lastObject];
  5. [self.randomColors removeObject:lastColor];
  6. [self.randomColors insertObject:lastColor atIndex:0];
  7. self.gaLineLayer.colors=self.randomColors;
  8. self.gaLayer.colors=self.randomColors;
  9. }
  10.  
  11. -(NSMutableArray*)randomColors
  12. {
  13. if (_randomColors==nil)
  14. {
  15. _randomColors=[NSMutableArray arrayWithArray:[self makeRandomColors]];
  16. }
  17. return _randomColors;
  18. }
  19.  
  20. -(NSArray *)makeRandomColors
  21. {
  22. NSArray *array= @[
  23. (id)[UIColor colorWithRed:0.5 green:0.1 blue:0.1 alpha:1].CGColor,//color 必须是CGColor强转来的
  24. (id)[UIColor colorWithRed:0.6 green:0.1 blue:0.1 alpha:1].CGColor,
  25. (id)[UIColor colorWithRed:0.7 green:0.1 blue:0.1 alpha:1].CGColor,
  26. (id)[UIColor colorWithRed:0.8 green:0.1 blue:0.1 alpha:1].CGColor,
  27. (id)[UIColor colorWithRed:0.9 green:0.1 blue:0.1 alpha:1].CGColor,
  28. ];
  29.  
  30. return array;
  31. }
  32.  
  33. -(void)drawRect:(CGRect)rect
  34. {
  35. [super drawRect:rect];
  36.  
  37. //这段代码放在这里的原因是 这段代码调用时,每个控件的frame 都已经设置好了
  38. //不放在layoutSubview 中是因为layoutSubview会调用多次,很难控制
  39. if (_colors.count>0)
  40. {
  41. CAGradientLayer *gaLayer=[CAGradientLayer layer];
  42. gaLayer.colors=_colors;
  43. gaLayer.frame=self.moneyLabel.frame;
  44. gaLayer.startPoint=CGPointMake(0, 0);
  45. gaLayer.endPoint=CGPointMake(1, 0);
  46. gaLayer.mask=self.moneyLabel.layer;
  47. self.moneyLabel.layer.frame=gaLayer.bounds;//这里需要设置一下frame 关于文字渐变的 可以上网搜一下袁征的博客
  48. self.gaLayer=gaLayer;
  49. [self.layer addSublayer:gaLayer];
  50.  
  51. CAGradientLayer *gaLineLayer=[CAGradientLayer layer];
  52. gaLineLayer.colors=_colors;
  53. gaLineLayer.frame=self.lineView.frame;
  54. gaLineLayer.startPoint=CGPointMake(0, 0);
  55. gaLineLayer.endPoint=CGPointMake(1, 0);
  56. self.gaLineLayer=gaLineLayer;
  57. [self.layer addSublayer:gaLineLayer];
  58.  
  59. if (self.needTwinkleColors)
  60. {
  61. CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(textColorChange)];
  62. link.frameInterval=20;//勉强可以设置刷新时间
  63. [link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
  64. }
  65. }
  66. }

自定义DZLMoneyLabel的更多相关文章

  1. 关于Unity3D自定义编辑器的学习

    被人物编辑器折腾了一个月,最终还是交了点成品上去(还要很多优化都还么做).  刚接手这项工作时觉得没概念,没想法,不知道.后来就去看<<Unity5.X从入门到精通>>中有关于 ...

  2. 一起学微软Power BI系列-使用技巧(5)自定义PowerBI时间日期表

    1.日期函数表作用 经常使用Excel或者PowerBI,Power Pivot做报表,时间日期是一个重要的纬度,加上做一些钻取,时间日期函数表不可避免.所以今天就给大家分享一个自定义的做日期表的方法 ...

  3. JavaScript自定义浏览器滚动条兼容IE、 火狐和chrome

    今天为大家分享一下我自己制作的浏览器滚动条,我们知道用css来自定义滚动条也是挺好的方式,css虽然能够改变chrome浏览器的滚动条样式可以自定义,css也能够改变IE浏览器滚动条的颜色.但是css ...

  4. ASP.NET Aries 入门开发教程8:树型列表及自定义右键菜单

    前言: 前面几篇重点都在讲普通列表的相关操作. 本篇主要讲树型列表的操作. 框架在设计时,已经把树型列表和普通列表全面统一了操作,用法几乎是一致的. 下面介绍一些差距化的内容: 1:树型列表绑定: v ...

  5. ASP.NET Aries 入门开发教程5:自定义列表页工具栏区

    前言: 抓紧时间,继续写教程,因为发现用户期待的内容,都在业务处理那一块. 不得不继续勤劳了. 这节主要介绍工具栏区的玩法. 工具栏的默认介绍: 工具栏默认包括5个按钮,根据不同的权限决定显示: 添加 ...

  6. UWP中实现自定义标题栏

    UWP中实现自定义标题栏 0x00 起因 在UWP开发中,有时候我们希望实现自定义标题栏,例如在标题栏中加入搜索框.按钮之类的控件.搜了下资料居然在一个日文网站找到了一篇介绍这个主题的文章: http ...

  7. JavaScript 自定义对象

    在Js中,除了Array.Date.Number等内置对象外,开发者可以通过Js代码创建自己的对象. 目录 1. 对象特性:描述对象的特性 2. 创建对象方式:对象直接量.new 构造函数.Objec ...

  8. 【WCF】自定义错误处理(IErrorHandler接口的用法)

    当被调用的服务操作发生异常时,可以直接把异常的原始内容传回给客户端.在WCF中,服务器传回客户端的异常,通常会使用 FaultException,该异常由这么几个东东组成: 1.Action:在服务调 ...

  9. 自定义Inspector检视面板

    Unity中的Inspector面板可以显示的属性包括以下两类:(1)C#以及Unity提供的基础类型:(2)自定义类型,并使用[System.Serializable]关键字序列化,比如: [Sys ...

随机推荐

  1. MySQL常用查询语句集合《转》

    一查询数值型数据: SELECT * FROM tb_name WHERE sum > 100; 查询谓词:>,=,<,<>,!=,!>,!<,=>,= ...

  2. esxi 5.1 由于断电错误无法启动 报错 bank5 invalid configuration

    由于着急,处理过程中也没有截图,这里简单的描写叙述下整个过程吧. IBM pcserver x3850 可能是机器太热的原因,中午无故掉电,导致esxi无法正常启动 启动时报错 bank5 inval ...

  3. hdu 5534 Partial Tree 背包DP

    Partial Tree Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid= ...

  4. Android学习笔记之百度地图

    步行路线搜索及RouteOverlay 方式与驾车路线搜索类似,只需将mMKSearch.drivingSearch(null, start, null, end)修改为mMKSearch.walki ...

  5. 在Linux使用mingw32来编写win32程序

    MinGW - Minimalist GNU For Windows Mingw32 是 GNU 計畫工具的集合,包含了大量的標頭檔(header files).函式庫與指 令程式.目的在提供免費的工 ...

  6. Scala Error: error while loading Suite, Scala signature Suite has wrong version expected: 5.0 found: 4.1 in Suite.class

    准备给scala项目引入单元测试 <dependency> <groupId>org.scalatest</groupId> <artifactId>s ...

  7. Boxes in a Line

    Boxes in a Line You have n boxes in a line on the table numbered 1 . . . n from left to right. Your ...

  8. Android防微信首页左右滑动切换

    大家看到微信首页切换效果有没有觉得很炫,滑动切换,点击底部bar瞬间切换,滑动切换渐变效果,线上效果图: 之前也在博客上看到别人的实现,再次基础上,我做了些优化.首先说下实现原理,大神略过,o(╯□╰ ...

  9. iOS之隐藏状态栏

    iOS7中,不仅应用的风格有一定的变化,状态栏变化比较大,我们可以看到UIViewController的状态栏与导航栏基本是一体的.因此UIVIEWCONTROLLER的hide/show状态的方法也 ...

  10. Selector中的各种状态详解

    今天弄这个selector把脑壳弄得清痛,最终我的理解如下: 官方关于这个的介绍在:http://developer.android.com/guide/topics/resources/drawab ...