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];
}

 

完成了圓形進度條的實現后,想了想,其實可以加入動畫,使得進度條動態展現,下次有時間再實現😁


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM