iOS开发笔记-根据frame大小动态调整fontSize的自适应文本及圆形进度条控件的实现

最近同样是新App,设计稿里出现一种圆形进度条的设计,如下:

想了想,圆形进度条实现起来不难,但是其中显示百分比的文本确需要自适应,虽然可以使用时自己设定文本字体的大小,但是这样显得很麻烦,也很low。

查了一圈,目前实现的自适应UILabel,都是根据font大小动态调整frame的size,并不能满足我们的需求。

 那么问题来了

如何实现一种能够根据frame大小自适应调整文本font size的圆形进度条呢?

我的实现思路很简单,首先计算出能够给予UILabel的frame最大尺寸,然后根据高度优先,宽度次之的原则,计算出最合适的字体大小,这样可以完美的适配各种尺寸。

效果如下:

实现代码:

CircleProgressBar继承于UIView,具有四个属性,分别如下:

//
//  CircleProgressBar.h
//  demo
//
//  Created by ZhangChangwei on 15/4/1.
//  Copyright (c) 2015年 Changwei. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface CircleProgressBar : UIView//进度条百分比值
@property (nonatomic) float percentValue;//进度条宽度
@property (nonatomic) float lineWidth;//文本颜色
@property (nonatomic ) UIColor *textColor;//进度条颜色
@property (nonatomic ) UIColor *barColor;
@end

实现方式主要采用CoreGraphics绘制图形,其中文字绘制采用自适应计算大小的方式实现,实现了根据控件frame大小动态改变字体的行为,非常灵活。

//
//  CircleProgressBar.m
//  demo
//
//  Created by ZhangChangwei on 15/4/1.
//  Copyright (c) 2015年 Changwei. All rights reserved.
//

#import "CircleProgressBar.h"

@implementation CircleProgressBar

/**
 *  init and set up property
 *
 *  @param frame <#frame description#>
 *
 *  @return <#return value description#>
 */
-(instancetype)initWithFrame:(CGRect)frame{
    self = [super initWithFrame:frame];
    if (self) {

    }
    return self;
}

/**
 *  redraw
 *
 *  @param rect frame
 */
 - (void)drawRect:(CGRect)rect {
     if(_lineWidth==0.0f){
         _percentValue=0;
         NSLog(@"%@",@"请输入颜色,数值等参数");
     }
         //开始绘制图形
         CGContextRef ctx=UIGraphicsGetCurrentContext();
         CGContextSetLineWidth(ctx, _lineWidth);
         CGContextBeginPath(ctx);
         CGContextSetStrokeColorWithColor(ctx, _barColor==nil?[UIColor orangeColor].CGColor:_barColor.CGColor);
         CGContextAddArc(ctx, self.frame.size.width/2, self.frame.size.width/2, self.frame.size.width/2-_lineWidth, M_PI*1.5, M_PI*(1.5-2*_percentValue), 1);
         CGContextStrokePath(ctx);
         //绘制计算最佳文本大小
         CGSize maxSize=CGSizeMake(rect.size.width*0.75, rect.size.height/3);
         int currentFontSize=17;
         NSString *str=[NSString stringWithFormat:@"%.1f%%",_percentValue*100];
         CGSize requiredSize = [str boundingRectWithSize:maxSize options:NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:currentFontSize]} context:nil].size;
         if(requiredSize.height<=maxSize.height)
         {
             while (requiredSize.height<=maxSize.height&&requiredSize.width<maxSize.width) {
                 currentFontSize++;
                 requiredSize=[str boundingRectWithSize:maxSize options:NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:currentFontSize]} context:nil].size;
             }
         }else
         {
             while (requiredSize.height>maxSize.height||requiredSize.width>maxSize.width) {
                 currentFontSize--;
                 requiredSize=[str boundingRectWithSize:maxSize options:NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:currentFontSize]} context:nil].size;
             }
             requiredSize=[str boundingRectWithSize:maxSize options:NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:currentFontSize]} context:nil].size;
         }
         //绘制自适应文本
         [str drawAtPoint:CGPointMake(rect.size.width/2-requiredSize.width/2, rect.size.height/2-requiredSize.height/2)
           withAttributes:@{
                            NSFontAttributeName:[UIFont systemFontOfSize:currentFontSize],
                            NSForegroundColorAttributeName:_textColor==nil?[UIColor blackColor]:_textColor
                            }];

     }

@end

使用方法:

CircleProgressBar使用起来非常简单,只需要提供相应参数即可,如下:

- (void)viewDidLoad {
    [super viewDidLoad];

    CircleProgressBar *bar1=[[CircleProgressBar alloc] initWithFrame:CGRectMake(SCREEN_WIDTH/2-10, SCREEN_HEIGHT*0.2, 20, 20)];
    bar1.barColor=[UIColor redColor];
    bar1.lineWidth=1.0f;
    bar1.percentValue=0.85;
    bar1.backgroundColor=[UIColor clearColor];
    [self.view addSubview:bar1];

    CircleProgressBar *bar2=[[CircleProgressBar alloc] initWithFrame:CGRectMake(SCREEN_WIDTH/2-25, SCREEN_HEIGHT*0.3, 50, 50)];
    bar2.barColor=[UIColor orangeColor];
    bar2.lineWidth=3;
    bar2.percentValue=0.45;
    bar2.backgroundColor=[UIColor clearColor];
    [self.view addSubview:bar2];
    CircleProgressBar *bar3=[[CircleProgressBar alloc] initWithFrame:CGRectMake(SCREEN_WIDTH/2-50, SCREEN_HEIGHT*0.5, 100, 100)];
    bar3.barColor=[UIColor greenColor];
    bar3.lineWidth=5;
    bar3.textColor=[UIColor blueColor];
    bar3.percentValue=0.75;
    bar3.backgroundColor=[UIColor clearColor];
    [self.view addSubview:bar3];
    CircleProgressBar *bar4=[[CircleProgressBar alloc] initWithFrame:CGRectMake(SCREEN_WIDTH/2-100, SCREEN_HEIGHT*0.7, 200, 200)];
    bar4.barColor=[UIColor blueColor];
    bar4.textColor=[UIColor purpleColor];
    bar4.lineWidth=10;
    bar4.percentValue=0.55;
    bar4.backgroundColor=[UIColor clearColor];
    [self.view addSubview:bar4];
}

完成了圆形进度条的实现后,想了想,其实可以加入动画,使得进度条动态展现,下次有时间再实现??

时间: 2024-10-18 22:15:48

iOS开发笔记-根据frame大小动态调整fontSize的自适应文本及圆形进度条控件的实现的相关文章

[转载]ExtJs4 笔记(8) Ext.slider 滚轴控件、 Ext.ProgressBar 进度条控件、 Ext.Editor 编辑控件

作者:李盼(Lipan)出处:[Lipan] (http://www.cnblogs.com/lipan/)版权声明:本文的版权归作者与博客园共有.转载时须注明本文的详细链接,否则作者将保留追究其法律责任. 本篇要登场的有三个控件,分别是滚轴控件.进度条控件和编辑控件. 一.滚轴控件 Ext.slider 1.滚轴控件的定义 下面我们定义三个具有代表意义滚轴控件,分别展示滚轴横向.纵向,以及单值.多值选择的特性: [html] <h1>滚轴控件</h1> <div class

iOS:进度条控件的详细使用

进度条控件:UIProcessView:UIView 功能:顾名思义,用来显示下载进度或者传输数据进度. 属性: @property(nonatomic) UIProgressViewStyle progressViewStyle; //风格类型 @property(nonatomic) float progress;                                   //当前进度 @property(nonatomic, retain) UIColor* progressTi

iOS项目开发实战——自定义圆形进度提示控件

iOS中默认的进度条是水平方向的进度条,这往往不能满足我们的需求.但是我们可以自定义类似的圆形的进度提示控件,主要使用iOS中的绘图机制来实现.这里我们要实现一个通过按钮点击然后圆形进度提示不断增加的效果. (1)新建一个Cocoa Touch Class,注意要继承自UIView.这个是绘制图形的类,绘制一个圆形的背景和扇形的进度.具体实现如下: import UIKit class ProgressControl: UIView { override init(frame: CGRect)

IOS 开发笔记-基础 UI(2)

1.公司标示一般使用反向域名 正向域名 www.xxx.com 用来标示一台网络主机,只要公司内部不重复就可以.反向域名 com.xxx.demo 用来标示产品,应该唯一标识. cn.com.abc.product,最后面是自己公司的产品名字 2..Bundle Identifier: 产品唯一标示符 Bundle ID = 公司的反向域名 + 产品名 1> 在模拟器上面,只能有一个唯一的标示符的应用程序2> 在AppStore上,所有的应用程序的Bundler ID都是唯一的 Bundle

IOS 开发笔记-基础 UI(3)按钮的使用(放大缩小、改变位置,首位式动画)和学习案例

UIKit框架提供了非常多的UI控件,但并不是每一个都很常用,有些控件可能1年内都用不上,有些控件天天用,比如UIButton.UILabel.UIImageView.UITableView等等,按钮控件是非常重要且比较基础的一个UI控件---UIButton,一般情况下,点击某个控件后,会做出相应反应的都是按钮,按钮的功能比较多,既能显示文字,又能显示图片,还能随时调整内部图片和文字的位置. 案例: 功能分析 (1)左下角4个方向按钮,控制头像按钮的位置 (2)右下角分别是放大.缩小按钮,控制

ios开发之根据内容行数调整cell 高度,与label高度

设置cell高度 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { NoticeMessage* msg = [arrayNoticeMessage objectAtIndex:indexPath.section];//取出对应的section或者cell UIFont *msgFont = [UIFont fontWithName:@"arial&qu

IOS开发笔记-百度地图(第三方库)

最近做了百度地图,在导入SDK后遇到了一些问题 编译错误: linker command failed with exit code 1 (use -v to see invocation) 想了很多办法,查了很多资料,最后终于解决. 可能原因: 1. 有重复的.m文件,或者未导入 解决办法:有重复的删除即可 在工作左边导航栏Target-->Build Phases-->compile Sources中,第三库库的所有.m文件都添加到里面 2.Valid Architectures 的值 在

ios开发笔记----exc_bad_access(code=1, address=0x789870)野指针错误,假死debug状态

错误原因: exc_bad_access(code=1, address=0x789870)野指针错误,主要的原因是,当某个对象被完全释放,也就是retainCount,引用计数为0后.再去通过该对象去调用其它的方法就会出现野指针错误. 例如: Person *jerry = [[Person alloc]init];  //  retainCount引用计数为1 [jerry eat];  //  调用吃的方法 [jerry release];  //  释放jerry这个对象到 retain

iOS开发笔记-两种单例模式的写法

iOS开发笔记-两种单例模式的写法 单例模式是开发中最常用的写法之一,iOS的单例模式有两种官方写法,如下: 不使用GCD #import "ServiceManager.h" static ServiceManager *defaultManager; @implementation ServiceManager +(ServiceManager *)defaultManager{ if(!defaultManager) defaultManager=[[self allocWith