zoukankan      html  css  js  c++  java
  • 自定义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];
            }
        }
    }
    
  • 相关阅读:
    20165309 Linux安装及学习
    20165309 技能学习经验与C语言
    20165309 我期望的师生关系
    20165317-我期望的师生关系
    20165308 学习基础和C语言基础调查
    20165308 我期望的师生关系
    20165320 结对编程学习第一周
    20165320 第七周学习总结
    20165320 第六周学习总结
    20165320 实验一 java环境的熟悉
  • 原文地址:https://www.cnblogs.com/dengzhuli/p/4851823.html
Copyright © 2011-2022 走看看