自定义DZLMoneyLabel
一、简介
由于父亲生病,好久没有更新博客了,今天10.1 国庆(应该说是昨天了,已经过了12点了),心血来潮自定义了一个小label。这个控件的难度并不大,也没有什么可以值得炫耀的技术点。写这个控件的主要原因是想再熟悉下label 和view 这连个最基本的控件。尽管天天接触这两个控件,但是我觉得很多初学者可能都并没有掌握这两个控件。废话不多说,先看一下效果图吧。
假装它可以闪动
二、思路
基本思路就是,先再初始化方法中创建所需要的控件,然后设置所需要的各种属性(注意各种属性之间可能会有先后顺序,但是使用者希望的是你给我提供的属性我可以随意顺序赋值,这也是我们需要解决的问题,实际上在大多数自定义控件中都会遇到这种问题),赋值完成之后进行各个控件的frame 设置,最后显示控件。下面先看一下头文件:
//
// DZLMoneyLabel.h
// StandUI
//
// Created by 邓竹立 on 15/10/1.
// Copyright (c) 2015年 GiveMeFive. All rights reserved.
// #import <UIKit/UIKit.h> typedef NS_ENUM(NSInteger, DZLMoneyType) {
DZLMoneyRMBNone,//啥也没有
DZLMoneyRMBSymbol,//¥
DZLMoneyRMBUnit,//元
DZLMoneyDollarSymbol,//$
}; @interface DZLMoneyLabel : UIView @property(nonatomic,assign)CGFloat money;//金额
@property(nonatomic,assign)NSInteger decimalPlace;//保留几位小数
@property(nonatomic,assign)NSInteger integerPartFontSize;//整数部分的字体大小
@property(nonatomic,assign)NSInteger decimalPartFontSize;//小数部分的字体大小
@property(nonatomic,assign)DZLMoneyType moneyType;//金钱类型,美元什么的
@property(nonatomic,assign)BOOL needCenterLine;//是否需要划线 @property(nonatomic,strong)NSArray *colors;//渐变色的颜色
@property(nonatomic,assign)BOOL needTwinkleColors;//是否需要闪烁效果 - (instancetype)initWithFrame:(CGRect)frame __attribute__((unavailable("就不让你用! 你能咋地?"))) NS_DESIGNATED_INITIALIZER; @end
头文件中所说的已经很清楚了,唯一要强调的就是最下面的代码,加上这段代码的可以堵住使用者的一些不当的初始化入口。比如说我只写了一个init 方法,懒得去处理initWithFrame方法,那么我就可以将这个方法堵住,使用者是收不到initWithFrame 的快捷提示的。这样的好处是可以减少使用者的疑惑,也可以减少我们的代码量,这个还不错吧?
三、代码解释
-(instancetype)init
{
if (self=[super init])
{
UILabel *moneyLabel=[[UILabel alloc] init];
self.moneyLabel=moneyLabel;
[self addSubview:moneyLabel]; UIView *lineView=[[UIView alloc] init];
self.lineView=lineView;
[self addSubview:lineView]; //默认
self.integerPartFontSize=13;
self.decimalPartFontSize=10;
self.moneyLabel.textColor=[UIColor orangeColor];
self.moneyLabel.textAlignment=NSTextAlignmentCenter;
self.lineView.backgroundColor=[UIColor orangeColor];
self.lineView.hidden=YES;
self.backgroundColor=[UIColor clearColor];
}
return self;
}
在初始化方法里,我主要是进行控件的创建,我的习惯就是先把所需要的控件先创建了再说,frame 等到layoutSubViews 的时候再设置,而且是所有的子视图的frame都在layoutSubViews中设置,集中起来将来好管理。在初始化方法中,需要给使用者一些必要的默认值。
下面是属性设置部分的代码:
-(void)setNeedCenterLine:(BOOL)needCenterLine
{
_needCenterLine=needCenterLine;
self.lineView.hidden=!_needCenterLine;
self.money=_money;
} -(void)setDecimalPlace:(NSInteger)decimalPlace
{
_decimalPlace=decimalPlace;
self.money=_money;
} -(void)setIntegerPartFontSize:(NSInteger)integerPartFontSize
{
_integerPartFontSize=integerPartFontSize;
self.money=_money;
} -(void)setDecimalPartFontSize:(NSInteger)decimalPartFontSize
{
_decimalPartFontSize=decimalPartFontSize;
self.money=_money;
} -(void)setColors:(NSArray *)colors
{
_colors=colors;
[self setNeedsLayout];//设置标记
[self layoutIfNeeded];//如果有标记立即调用
} -(void)setMoney:(CGFloat)money
{
_money=money;
NSString *moneyStr=[self stringByPrecisionWithMoney:_money];//其实就是选择显示的精度
moneyStr=[self addMoneyTypeWithString:moneyStr];//添加人民币符号等 NSMutableAttributedString *attrString=[[NSMutableAttributedString alloc] initWithString:moneyStr attributes:nil];
NSRange range=[moneyStr rangeOfString:@"."]; NSString *integerPartStr;
NSString *decimalPartStr;
if (range.length>0)
{
integerPartStr=[moneyStr substringToIndex:range.location];
decimalPartStr=[moneyStr substringFromIndex:range.location+1];
NSRange integerPartRange=[moneyStr rangeOfString:integerPartStr];
NSRange decimalPartRange=[moneyStr rangeOfString:decimalPartStr];
[attrString addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"Helvetica" size:self.integerPartFontSize] range:integerPartRange];
[attrString addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"Helvetica" size:self.decimalPartFontSize] range:decimalPartRange];
}else
{
integerPartStr=moneyStr;
decimalPartStr=@"";
NSRange integerPartRange=[moneyStr rangeOfString:integerPartStr];
[attrString addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"Helvetica" size:self.integerPartFontSize] range:integerPartRange];
} self.moneyLabel.attributedText=attrString;
[self setColors:_colors];
} -(NSString*)stringByPrecisionWithMoney:(CGFloat)money
{
NSString *moneyStr;
if (self.decimalPlace==0)
{
moneyStr=[NSString stringWithFormat:@"%.0f",money];
}else if(self.decimalPlace==1)
{
moneyStr=[NSString stringWithFormat:@"%.1f",money];
}else if (self.decimalPlace==2)
{
moneyStr=[NSString stringWithFormat:@"%.2f",money];
}else
{
moneyStr=[NSString stringWithFormat:@"%g",money];
}
return moneyStr;
} -(NSString *)addMoneyTypeWithString:(NSString*)moneyStr
{
switch (self.moneyType)
{
case DZLMoneyRMBSymbol:
{
moneyStr=[@"¥" stringByAppendingString:moneyStr];
}
break; case DZLMoneyRMBUnit:
{
moneyStr=[moneyStr stringByAppendingString:@"元"];
}
break; case DZLMoneyDollarSymbol:
{
moneyStr=[@"$" stringByAppendingString:moneyStr];
}
break; default:
break;
}
return moneyStr;
}
以上代码其实不用细看,其基本思路就是先设置精度、金钱类型等属性,然后再设置金额、最后设置渐变色。如果使用者不小心把顺序搞错了,那么我们就再手动帮他们把顺序纠正过来。比如再设置精度的方法内部调用设置金额的方法。这里再说一下layoutIfNeed 和 setNeedsLayout。 setNeedsLayout其实是做了一个标记:告诉系统某控件需要调用layoutSubViews 了,但是什么时候掉我不管。layoutIfNeed其实是一次检查:这个控件有没有刷新标记啊?有的话我立马调用layoutSubViews。置于layoutSubViews方法,那就没什么可说的了:
-(void)layoutSubviews
{
[super layoutSubviews];
[self.moneyLabel sizeToFit];
self.bounds=CGRectMake(0, 0, self.moneyLabel.bounds.size.width, self.moneyLabel.bounds.size.height);
self.moneyLabel.frame=self.bounds; if (!self.needCenterLine)
{
return;
}
const CGFloat lineH=1.25;
self.lineView.frame=CGRectMake(0,self.bounds.size.height*0.5 , self.bounds.size.width, lineH);
}
其他的只要看代码里的注释就可以了,总的来说在写这段代码时候遇到挺多坑的,不过还是很有收获,对UIView 又加深了印象。最后说两句题外话:程序员需要不断地去学习。程序员需要向其他程序员学习。拜拜各位,睡觉喽~
-(void)textColorChange
{
//颜色交替
id lastColor=[self.randomColors lastObject];
[self.randomColors removeObject:lastColor];
[self.randomColors insertObject:lastColor atIndex:0];
self.gaLineLayer.colors=self.randomColors;
self.gaLayer.colors=self.randomColors;
} -(NSMutableArray*)randomColors
{
if (_randomColors==nil)
{
_randomColors=[NSMutableArray arrayWithArray:[self makeRandomColors]];
}
return _randomColors;
} -(NSArray *)makeRandomColors
{
NSArray *array= @[
(id)[UIColor colorWithRed:0.5 green:0.1 blue:0.1 alpha:1].CGColor,//color 必须是CGColor强转来的
(id)[UIColor colorWithRed:0.6 green:0.1 blue:0.1 alpha:1].CGColor,
(id)[UIColor colorWithRed:0.7 green:0.1 blue:0.1 alpha:1].CGColor,
(id)[UIColor colorWithRed:0.8 green:0.1 blue:0.1 alpha:1].CGColor,
(id)[UIColor colorWithRed:0.9 green:0.1 blue:0.1 alpha:1].CGColor,
]; return array;
} -(void)drawRect:(CGRect)rect
{
[super drawRect:rect]; //这段代码放在这里的原因是 这段代码调用时,每个控件的frame 都已经设置好了
//不放在layoutSubview 中是因为layoutSubview会调用多次,很难控制
if (_colors.count>0)
{
CAGradientLayer *gaLayer=[CAGradientLayer layer];
gaLayer.colors=_colors;
gaLayer.frame=self.moneyLabel.frame;
gaLayer.startPoint=CGPointMake(0, 0);
gaLayer.endPoint=CGPointMake(1, 0);
gaLayer.mask=self.moneyLabel.layer;
self.moneyLabel.layer.frame=gaLayer.bounds;//这里需要设置一下frame 关于文字渐变的 可以上网搜一下袁征的博客
self.gaLayer=gaLayer;
[self.layer addSublayer:gaLayer]; CAGradientLayer *gaLineLayer=[CAGradientLayer layer];
gaLineLayer.colors=_colors;
gaLineLayer.frame=self.lineView.frame;
gaLineLayer.startPoint=CGPointMake(0, 0);
gaLineLayer.endPoint=CGPointMake(1, 0);
self.gaLineLayer=gaLineLayer;
[self.layer addSublayer:gaLineLayer]; if (self.needTwinkleColors)
{
CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(textColorChange)];
link.frameInterval=20;//勉强可以设置刷新时间
[link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
}
}
}
自定义DZLMoneyLabel的更多相关文章
- 关于Unity3D自定义编辑器的学习
被人物编辑器折腾了一个月,最终还是交了点成品上去(还要很多优化都还么做). 刚接手这项工作时觉得没概念,没想法,不知道.后来就去看<<Unity5.X从入门到精通>>中有关于 ...
- 一起学微软Power BI系列-使用技巧(5)自定义PowerBI时间日期表
1.日期函数表作用 经常使用Excel或者PowerBI,Power Pivot做报表,时间日期是一个重要的纬度,加上做一些钻取,时间日期函数表不可避免.所以今天就给大家分享一个自定义的做日期表的方法 ...
- JavaScript自定义浏览器滚动条兼容IE、 火狐和chrome
今天为大家分享一下我自己制作的浏览器滚动条,我们知道用css来自定义滚动条也是挺好的方式,css虽然能够改变chrome浏览器的滚动条样式可以自定义,css也能够改变IE浏览器滚动条的颜色.但是css ...
- ASP.NET Aries 入门开发教程8:树型列表及自定义右键菜单
前言: 前面几篇重点都在讲普通列表的相关操作. 本篇主要讲树型列表的操作. 框架在设计时,已经把树型列表和普通列表全面统一了操作,用法几乎是一致的. 下面介绍一些差距化的内容: 1:树型列表绑定: v ...
- ASP.NET Aries 入门开发教程5:自定义列表页工具栏区
前言: 抓紧时间,继续写教程,因为发现用户期待的内容,都在业务处理那一块. 不得不继续勤劳了. 这节主要介绍工具栏区的玩法. 工具栏的默认介绍: 工具栏默认包括5个按钮,根据不同的权限决定显示: 添加 ...
- UWP中实现自定义标题栏
UWP中实现自定义标题栏 0x00 起因 在UWP开发中,有时候我们希望实现自定义标题栏,例如在标题栏中加入搜索框.按钮之类的控件.搜了下资料居然在一个日文网站找到了一篇介绍这个主题的文章: http ...
- JavaScript 自定义对象
在Js中,除了Array.Date.Number等内置对象外,开发者可以通过Js代码创建自己的对象. 目录 1. 对象特性:描述对象的特性 2. 创建对象方式:对象直接量.new 构造函数.Objec ...
- 【WCF】自定义错误处理(IErrorHandler接口的用法)
当被调用的服务操作发生异常时,可以直接把异常的原始内容传回给客户端.在WCF中,服务器传回客户端的异常,通常会使用 FaultException,该异常由这么几个东东组成: 1.Action:在服务调 ...
- 自定义Inspector检视面板
Unity中的Inspector面板可以显示的属性包括以下两类:(1)C#以及Unity提供的基础类型:(2)自定义类型,并使用[System.Serializable]关键字序列化,比如: [Sys ...
随机推荐
- uistepper on ios versions prior to 5.0
xcode5 打开运行就出现这个错误 uistepper on ios versions prior to 5.0 直接在General -->Deployment Info -->Dep ...
- 【转】Rails 3.1错误-Could not find a JavaScript runtime及execjs和therubyracer介绍
转自:http://rubyer.me/blog/740/ Rails 3.1错误 /gems/execjs-1.1.2/lib/ execjs/runtimes.rb:43:in `autodete ...
- centos6.4上安装phpmyfaq
phpmyfaq真是奇怪呀,官网上只能下载到当前的版本,无法下载以前的版本.官网为:http://www.phpmyfaq.de/ 官网上没有phpmyfaq的安装方法,我在网上找了下,这就个文章还比 ...
- ResultSet转成java类对象
在做web开发时遇到一个事情: 需要从mysql数据表中查询数据并遍历查询结果 这样最简单的方式是:查询到结果根据表中字段列表的顺序来一个个获取字段,但这样需要记住字段的顺序,操作起来不是那么方便.因 ...
- Html页中使用OCX控件
原文:http://blog.csdn.net/mouse8166/article/details/5515657 最近准备开发一个b/s架构的应用程序需要用到activeX控件,web服务器尚未进入 ...
- 个人对maven pom.xml文件的理解
如:一个项目可能需要引用另外两个项目的类.. 如 项目cswebbefore 需要引用cswebservice 和reports 这三个项目都有各自的pom.xml文件 cswebservice 项 ...
- 【Android】利用服务Service创建标题栏通知
创建标题栏通知的核心代码 public void CreateInform() { //定义一个PendingIntent,当用户点击通知时,跳转到某个Activity(也可以发送广播等) Inten ...
- [Angular 2] How To Debug An Angular 2 Application - Debugging via Augury or the Console
In this lesson we will learn several ways to debug an Angular 2 application, including by using Augu ...
- iOS开发——混编Swift篇&OC移植为swift
将Ojective-C代码移植转换为Swift代码 2015-03-09 15:07发布:yuhang浏览:201 相比于Objective-C,Swift语言更加简练.有时我们需要把原来写的一些 ...
- 利用text插件和css插件优化web应用
JavaScript的模块化开发到如今,已经相当成熟了,当然,一个应用包含的不仅仅有js,还有html模板和css文件. 那么,如何将html和css也一起打包,来减少没必要的HTTP请求数呢? 本文 ...