iOS - 動(dòng)態(tài)折線圖繪制

前言:

最近公司在藍(lán)牙設(shè)備,需要按照通過設(shè)備讀取的數(shù)據(jù)來實(shí)時(shí)畫出折線圖,參考了很多資料,然后自己封裝了一套畫折線圖的方法(支持畫封閉圖形,四邊形,三角形),如果有需要的小伙伴可以拿去,效果圖如下:

Untitled001.gif
Untitled.gif
Untitled002.gif
首先

我自定義了一個(gè)專門真是折線圖的 View ,我新建的時(shí)候用了 xib, 當(dāng)然不用也是可以的只需要自己手動(dòng)調(diào)一下就好了


Paste_Image.png
具體實(shí)現(xiàn)方法如下:
- SportLineView.h

#import <UIKit/UIKit.h>

typedef NS_ENUM(NSUInteger, ChartType) {
    /** 四邊形*/
    QuadrilateralType = 1,
    /** 三角形 */
    TriangleType = 2
};

@interface SportLineView : UIView
// x軸值
@property (nonatomic, copy) NSArray *xValues;

// y軸值
@property (nonatomic, copy) NSArray *yValues;

// 繪圖數(shù)組
@property (strong, nonatomic) NSMutableArray *pointArray;

// 是否顯示方格
@property (nonatomic, assign) bool isShowLine;

// 初始化折線圖所在視圖
+ (instancetype)lineChartViewWithFrame:(CGRect)frame;
// 畫圖表
- (void)drawChartWithLineChart;

// 封閉圖形類型
@property (nonatomic, assign) ChartType type;

// 即時(shí)更新折線圖
- (void)exchangeLineAnyTime;

// 一類肌疲勞度
- (CGFloat)getFirstMuscleLevel;
// 二類肌疲勞度
- (CGFloat)getSecondMuscleLevel;

@end
- SportLineView.m
#import "SportLineView.h"

static CGRect myFrame;
static int count;   // 點(diǎn)個(gè)數(shù),x軸格子數(shù)
static int yCount;  // y軸格子數(shù)
static CGFloat everyX;  // x軸每個(gè)格子寬度
static CGFloat everyY;  // y軸每個(gè)格子高度
static CGFloat maxY;    // 最大的y值
static CGFloat allH;    // 整個(gè)圖表高度
static CGFloat allW;    // 整個(gè)圖表寬度
#define kMargin 30

@interface SportLineView()
@property (weak, nonatomic) IBOutlet UIView *bgView;
@property (strong, nonatomic) NSMutableArray *xLabels;

@end

@implementation SportLineView

+ (instancetype)lineChartViewWithFrame:(CGRect)frame{
    SportLineView *lineChartView = [[NSBundle mainBundle] loadNibNamed:@"SportLineView" owner:self options:nil].lastObject;
    lineChartView.frame = frame;
    
    myFrame = frame;
    
    return lineChartView;
}

#pragma mark - 計(jì)算

- (void)doWithCalculate{
    if (!self.xValues || !self.xValues.count || !self.yValues || !self.yValues.count) {
        return;
    }
    // 移除多余的值,計(jì)算點(diǎn)個(gè)數(shù)
    if (self.xValues.count > self.yValues.count) {
        NSMutableArray * xArr = [self.xValues mutableCopy];
        for (int i = 0; i < self.xValues.count - self.yValues.count; i++){
            [xArr removeLastObject];
        }
        self.xValues = [xArr mutableCopy];
    }else if (self.xValues.count < self.yValues.count){
        NSMutableArray * yArr = [self.yValues mutableCopy];
        for (int i = 0; i < self.yValues.count - self.xValues.count; i++){
            [yArr removeLastObject];
        }
        self.yValues = [yArr mutableCopy];
    }
    
    count = (int)self.xValues.count;
    
    everyX = (CGFloat)(CGRectGetWidth(myFrame) - kMargin * 2) / count;
    
    // y軸最多分5部分
    yCount = count <= 10 ? count : 10;
    
    everyY =  (CGRectGetHeight(myFrame) - kMargin * 2) / yCount;
    
    maxY = CGFLOAT_MIN;
    for (int i = 0; i < count; i ++) {
        if ([self.yValues[i] floatValue] > maxY) {
            maxY = [self.yValues[i] floatValue];
        }
    }
    
    allH = CGRectGetHeight(myFrame) - kMargin * 2;
    allW = CGRectGetWidth(myFrame) - kMargin * 2;
}

#pragma mark - 畫X、Y軸
- (void)drawXYLine{
    
    UIBezierPath *path = [UIBezierPath bezierPath];
    
    [path moveToPoint:CGPointMake(kMargin, kMargin / 2.0 - 5)];
    
    [path addLineToPoint:CGPointMake(kMargin, CGRectGetHeight(myFrame) - kMargin)];
    [path addLineToPoint:CGPointMake(CGRectGetWidth(myFrame) - kMargin / 2.0 + 5, CGRectGetHeight(myFrame) - kMargin)];
    
    // 加箭頭
    [path moveToPoint:CGPointMake(kMargin - 5, kMargin/ 2.0 + 4)];
    [path addLineToPoint:CGPointMake(kMargin, kMargin / 2.0 - 4)];
    [path addLineToPoint:CGPointMake(kMargin + 5, kMargin/ 2.0 + 4)];
    
    [path moveToPoint:CGPointMake(CGRectGetWidth(myFrame) - kMargin / 2.0 - 4, CGRectGetHeight(myFrame) - kMargin - 5)];
    [path addLineToPoint:CGPointMake(CGRectGetWidth(myFrame) - kMargin / 2.0 + 5, CGRectGetHeight(myFrame) - kMargin)];
    [path addLineToPoint:CGPointMake(CGRectGetWidth(myFrame) - kMargin / 2.0 - 4, CGRectGetHeight(myFrame) - kMargin + 5)];
    
    CAShapeLayer *layer = [[CAShapeLayer alloc] init];
    layer.path = path.CGPath;
    layer.strokeColor = [UIColor brownColor].CGColor;
    layer.fillColor = [UIColor clearColor].CGColor;
    layer.lineWidth = 2.0;
    
    [self.layer addSublayer:layer];
}

#pragma mark - 添加label
- (void)drawLabels{
    
    
    //Y軸
    for(int i = 0; i <= yCount; i ++){
        UILabel *lbl = [[UILabel alloc] initWithFrame:CGRectMake(0, kMargin  + everyY * i - everyY / 2, kMargin - 1, everyY)];
        lbl.textColor = [UIColor blackColor];
        lbl.font = [UIFont systemFontOfSize:10];
        lbl.textAlignment = NSTextAlignmentRight;
        
        lbl.text = [NSString stringWithFormat:@"%d%%", (int)(maxY / yCount * (yCount - i)) ];
        
        [self addSubview:lbl];
    }
    
    // X軸
    for(int i = 1; i <= count; i ++){
        UILabel *lbl = [[UILabel alloc] initWithFrame:CGRectMake(kMargin + everyX * i - everyX / 2, CGRectGetHeight(myFrame) - kMargin, everyX, kMargin)];
        
        lbl.textColor = [UIColor blackColor];
        lbl.font = [UIFont systemFontOfSize:12];
        lbl.textAlignment = NSTextAlignmentCenter;
        
        [self.xLabels addObject:lbl];
        // 如果起點(diǎn)不是0,計(jì)算橫軸的坐標(biāo)值
        NSValue *pointObj = [self.pointArray lastObject];
        CGPoint pointRestored = [pointObj CGPointValue];
        
        CGFloat maxX = pointRestored.x;
        int maxValueX = (int)maxX;
        CGFloat xfloat = maxX - maxValueX;
        if (xfloat > 0) {
            maxValueX += 1;
        }
        
//        NSValue *firstPointObj = [self.pointArray firstObject];
//        CGPoint firstPointRestored = [firstPointObj CGPointValue];
        
        if (maxValueX <= count) {
            lbl.text = [NSString stringWithFormat:@"%@", self.xValues[i - 1]];
        }else{
            lbl.text = [NSString stringWithFormat:@"%zd", maxValueX - count + i];
        }
        
        [self addSubview:lbl];
    }
    
}

#pragma mark - 畫網(wǎng)格
- (void)drawLines{
    
    UIBezierPath *path = [UIBezierPath bezierPath];
    // 橫線
    for (int i = 0; i < yCount; i ++) {
        [path moveToPoint:CGPointMake(kMargin , kMargin + everyY * i)];
        [path addLineToPoint:CGPointMake(kMargin + allW ,  kMargin + everyY * i)];
    }
    // 豎線
    for (int i = 1; i <= count; i ++) {
        [path moveToPoint:CGPointMake(kMargin + everyX * i, kMargin)];
        [path addLineToPoint:CGPointMake( kMargin + everyX * i,  kMargin + allH)];
    }
    
    CAShapeLayer *layer = [[CAShapeLayer alloc] init];
    layer.path = path.CGPath;
    layer.strokeColor = [UIColor lightGrayColor].CGColor;
    layer.fillColor = [UIColor clearColor].CGColor;
    layer.lineWidth = 0.5;
    [self.layer addSublayer:layer];
    
}

#pragma mark - 畫折線\曲線
- (void)drawFoldLineWithLineChart{

    
    UIBezierPath *path = [UIBezierPath bezierPath];

    NSValue *pointObj = [self.pointArray firstObject];
    CGPoint pointRestored = [pointObj CGPointValue];
    CGFloat xpoint = pointRestored.x;
    CGFloat ypoint = pointRestored.y;
    int maxValueX = count;
    
    CGFloat Xwidth = (CGFloat)(CGRectGetWidth(myFrame) - kMargin * 2);
    
    if (xpoint <= 0) {
        [path moveToPoint:CGPointMake(kMargin, kMargin + allH)];
    }else{
        // 如果起點(diǎn)不是0,計(jì)算橫軸的坐標(biāo)值
        
        NSValue *MaxpointObj = [self.pointArray lastObject];
        CGPoint MaxpointRestored = [MaxpointObj CGPointValue];
        
        CGFloat maxX = MaxpointRestored.x;
        maxValueX = (int)maxX;
        CGFloat xfloat = maxX - maxValueX;
        if (xfloat > 0) {
            maxValueX += 1;
        }
        
        if (maxValueX <= count) {
            [path moveToPoint:CGPointMake(kMargin + xpoint * Xwidth / count, kMargin + (1 - ypoint / maxY) * allH)];
            
        }else{
            for (int i = 1; i < self.pointArray.count; i ++) {
                NSValue *pointObj = self.pointArray[i];
                CGPoint pointRestored = [pointObj CGPointValue];
                
                
                if (pointRestored.x >= (maxValueX - count)) {
                    [path moveToPoint:CGPointMake(kMargin + (pointRestored.x - (maxValueX - count))* Xwidth / count, kMargin + (1 - pointRestored.y / maxY) * allH)];
                    i = (int)(self.pointArray.count + 1);
                    
                }
            }
        }
        
        
        
    }
    for (int i = 1; i < self.pointArray.count; i ++) {
        NSValue *pointObj = self.pointArray[i];
        CGPoint pointRestored = [pointObj CGPointValue];
        
        
        if (maxValueX <= count) {
            [path addLineToPoint:CGPointMake(kMargin + pointRestored.x* Xwidth / count, kMargin + (1 - pointRestored.y / maxY) * allH)];
        }else{
            if (pointRestored.x >= (maxValueX - count)) {
                [path addLineToPoint:CGPointMake(kMargin + (pointRestored.x - (maxValueX - count))* Xwidth / count, kMargin + (1 - pointRestored.y / maxY) * allH)];
            }
        }
    }
    
    if (self.pointArray.count == 0) {
        [path addLineToPoint:CGPointMake(kMargin, kMargin + allH)];
    }
    
    CAShapeLayer *layer = [[CAShapeLayer alloc] init];
    layer.path = path.CGPath;
    layer.strokeColor = [UIColor redColor].CGColor;
    layer.fillColor = [UIColor clearColor].CGColor;
    
    [self.bgView.layer addSublayer:layer];
    
}

#pragma mark - 整合 畫圖表
- (void)drawChartWithLineChart{
    
    // 計(jì)算賦值
    [self doWithCalculate];
    
    // 畫網(wǎng)格線
    if (self.isShowLine) {
        [self drawLines];
    }
    
    // 畫X、Y軸
    [self drawXYLine];
    
    // 添加文字
    [self drawLabels];
    
    // 畫封閉圖形
    if (self.type == QuadrilateralType) {
        NSMutableArray *points = [NSMutableArray array];
        CGPoint point1 = CGPointMake(1.5, 0);
        NSValue *pointObj1 = [NSValue valueWithCGPoint:point1];
        [points addObject:pointObj1];
        
        CGPoint point2 = CGPointMake(2, 45);
        NSValue *pointObj2 = [NSValue valueWithCGPoint:point2];
        [points addObject:pointObj2];
        
        CGPoint point3 = CGPointMake(8, 45);
        NSValue *pointObj3 = [NSValue valueWithCGPoint:point3];
        [points addObject:pointObj3];
        
        CGPoint point4 = CGPointMake(8.5, 0);
        NSValue *pointObj4 = [NSValue valueWithCGPoint:point4];
        [points addObject:pointObj4];
        
        [self drawClosedQuadrilateralChartWithArray:points];
    }else if(self.type == TriangleType){
        
        for (int i = 0; i < 5; i ++) {
            NSMutableArray *points = [NSMutableArray array];
            CGPoint point1 = CGPointMake(2 * (i+ 1), 0);
            NSValue *pointObj1 = [NSValue valueWithCGPoint:point1];
            [points addObject:pointObj1];
            
            CGPoint point2 = CGPointMake(2 * (i+ 1) + 0.5, 100);
            NSValue *pointObj2 = [NSValue valueWithCGPoint:point2];
            [points addObject:pointObj2];
            
            CGPoint point3 = CGPointMake(2 * (i+ 1) + 1, 0);
            NSValue *pointObj3 = [NSValue valueWithCGPoint:point3];
            [points addObject:pointObj3];
            [self drawClosedQuadrilateralChartWithArray:points];
        }
    }
    
    
    
}
// 更新折線圖, X軸坐標(biāo)
- (void)exchangeLineAnyTime{
    // 計(jì)算賦值
    [self doWithCalculate];
    
    NSArray *layers = [self.bgView.layer.sublayers mutableCopy];
    
    for (CAShapeLayer *layer in layers) {
        [layer removeFromSuperlayer];
    }
    // 畫折線
    [self drawFoldLineWithLineChart];
    
    [self exchangeXlabels];
}
- (void)exchangeXlabels{
    NSValue *pointObj = [self.pointArray lastObject];
    CGPoint pointRestored = [pointObj CGPointValue];
    
    CGFloat maxX = pointRestored.x;
    int maxValueX = (int)maxX;
    CGFloat xfloat = maxX - maxValueX;
    if (xfloat > 0) {
        maxValueX += 1;
    }
    
    if (maxValueX > count) {
        for (int i = 0; i < self.xLabels.count; i ++) {
            UILabel *label = self.xLabels[i];
            label.text = [NSString stringWithFormat:@"%zd", maxValueX - count + i + 1];
        }
    }
    
}

// 封閉圖形
- (void)drawClosedQuadrilateralChartWithArray:(NSArray *)points{
    
    UIBezierPath *path = [UIBezierPath bezierPath];
    CGFloat Xwidth = (CGFloat)(CGRectGetWidth(myFrame) - kMargin * 2);
    
    for (int i = 0; i < points.count; i ++) {
        NSValue *pointObj = points[i];
        CGPoint pointRestored = [pointObj CGPointValue];
        if (i == 0) {
            [path moveToPoint:CGPointMake(kMargin + pointRestored.x * Xwidth / count, kMargin + (1 - pointRestored.y / maxY) * allH)];
        }else{
            [path addLineToPoint:CGPointMake(kMargin + pointRestored.x * Xwidth / count, kMargin + (1 - pointRestored.y / maxY) * allH)];
        }
    }
    
    [path closePath];

    CAShapeLayer *layer = [[CAShapeLayer alloc] init];
    layer.path = path.CGPath;
    layer.strokeColor = [UIColor lightGrayColor].CGColor;
    layer.fillColor = SSColorA(255, 255, 155, 100.0).CGColor;
    
    [self.layer addSublayer:layer];
    
}
#pragma mark -- 一類肌疲勞度
- (CGFloat)getFirstMuscleLevel{
    
    CGPoint startPoint = [self exchangeXYValuePoint:CGPointMake(2, 40)];
    CGPoint endPoint = [self exchangeXYValuePoint:CGPointMake(7, 40)];
    
    CGFloat totalArea = (endPoint.x - startPoint.x) * endPoint.y;
    
    CGFloat trapezoidal = 0;
    for (int i = 0; i < self.pointArray.count; i ++) {
        NSValue *pointObj = self.pointArray[i];
        CGPoint pointRestored = [pointObj CGPointValue];
        
        
        if (pointRestored.x >= 2 && pointRestored.x <= 7) {
            
            NSValue *pointObj2 = self.pointArray[i + 1];
            CGPoint pointRestored2 = [pointObj2 CGPointValue];
            
            CGPoint point1 = pointRestored;
            CGPoint point2 = pointRestored2;
            
            CGFloat area = [self getTrapezoidalAreaWithPoint1:point1 poit2:point2];
            trapezoidal += area;
        }
    }
    
    // 計(jì)算肌力疲勞度
    
    CGFloat level = trapezoidal / totalArea;

    return level;
}
#pragma mark -- 二類肌疲勞度
- (CGFloat)getSecondMuscleLevel{
    CGPoint startPoint = [self exchangeXYValuePoint:CGPointMake(2, 0)];
    CGPoint endPoint = [self exchangeXYValuePoint:CGPointMake(3, 0)];
    CGPoint topPoint = [self exchangeXYValuePoint:CGPointMake(2.5, 100)];
    
    CGFloat triangle = (endPoint.x - startPoint.x) * topPoint.y * 0.5;
    CGFloat totalArea = 5 * triangle;
    
    CGFloat trapezoidal = 0;
    
    for (int i = 0; i < self.pointArray.count; i ++) {
        NSValue *pointObj = self.pointArray[i];
        CGPoint pointRestored = [pointObj CGPointValue];
       
        if (pointRestored.x >= 2 && pointRestored.x <= 3) {
            
            NSValue *pointObj2 = self.pointArray[i + 1];
            CGPoint pointRestored2 = [pointObj2 CGPointValue];
            
            CGPoint point1 = pointRestored;
            CGPoint point2 = pointRestored2;
            
            CGFloat area = [self getTrapezoidalAreaWithPoint1:point1 poit2:point2];
            trapezoidal += area;

        }else if (pointRestored.x >= 4 && pointRestored.x <= 5){
            NSValue *pointObj2 = self.pointArray[i + 1];
            CGPoint pointRestored2 = [pointObj2 CGPointValue];
            
            CGPoint point1 = pointRestored;
            CGPoint point2 = pointRestored2;
            
            CGFloat area = [self getTrapezoidalAreaWithPoint1:point1 poit2:point2];
            trapezoidal += area;
        }else if (pointRestored.x >= 6 && pointRestored.x <= 7){
            NSValue *pointObj2 = self.pointArray[i + 1];
            CGPoint pointRestored2 = [pointObj2 CGPointValue];
            
            CGPoint point1 = pointRestored;
            CGPoint point2 = pointRestored2;
            
            CGFloat area = [self getTrapezoidalAreaWithPoint1:point1 poit2:point2];
            trapezoidal += area;
        }else if (pointRestored.x >= 8 && pointRestored.x <= 9){
            NSValue *pointObj2 = self.pointArray[i + 1];
            CGPoint pointRestored2 = [pointObj2 CGPointValue];
            
            CGPoint point1 = pointRestored;
            CGPoint point2 = pointRestored2;
            
            CGFloat area = [self getTrapezoidalAreaWithPoint1:point1 poit2:point2];
            trapezoidal += area;
        }else if (pointRestored.x >= 10 && pointRestored.x <= 11){
            NSValue *pointObj2 = self.pointArray[i + 1];
            CGPoint pointRestored2 = [pointObj2 CGPointValue];
            
            CGPoint point1 = pointRestored;
            CGPoint point2 = pointRestored2;
            
            CGFloat area = [self getTrapezoidalAreaWithPoint1:point1 poit2:point2];
            trapezoidal += area;
        }
    }
    // 計(jì)算肌力疲勞度
    
    CGFloat level = trapezoidal / totalArea;
    
    return level;
}

// 計(jì)算兩坐標(biāo)點(diǎn)之間的梯形面積
- (CGFloat)getTrapezoidalAreaWithPoint1:(CGPoint)point1 poit2:(CGPoint)point2{
    
    CGPoint expoint1 = [self exchangeXYValuePoint:point1];
    CGPoint expoint2 = [self exchangeXYValuePoint:point2];
    
    CGFloat expoint1X = expoint1.x;
    CGFloat expoint1y = expoint1.y;
    
    CGFloat expoint2X = expoint2.x;
    CGFloat expoint2y = expoint2.y;
    
    CGFloat area = (expoint1y + expoint2y) * (expoint2X - expoint1X) * 0.5;
    
    return area;
}
// 根據(jù)一個(gè)點(diǎn)轉(zhuǎn)換坐標(biāo)值
- (CGPoint)exchangeXYValuePoint:(CGPoint)point{
    
    CGFloat Xwidth = (CGFloat)(CGRectGetWidth(myFrame) - kMargin * 2);

    CGPoint zeroPoint;
    zeroPoint.x = kMargin + 0 * Xwidth / count;
    zeroPoint.y =  kMargin + (1 - 0 / maxY) * allH;
    
    CGPoint linePoint;
    linePoint.x = kMargin + point.x * Xwidth / count - zeroPoint.x;
    linePoint.y = zeroPoint.y - ( kMargin + (1 - point.y / maxY) * allH );
    return linePoint;
}
#pragma mark -- 懶加載
- (NSMutableArray *)pointArray{
    if (!_pointArray) {
        _pointArray = [NSMutableArray array];
    }
    return _pointArray;
}
- (NSMutableArray *)xLabels{
    if (!_xLabels) {
        _xLabels = [NSMutableArray array];
    }
    return _xLabels;
}

@end
具體使用方法:
  • 初始化:
 SportLineView *LCView = [SportLineView lineChartViewWithFrame:CGRectMake(10, 0, CGRectGetWidth([UIScreen mainScreen].bounds) - 20, self.topView.frame.size.height)];
    LCView.xValues = @[@1, @2, @3, @4, @5, @6, @7,@8, @9, @10];
    LCView.yValues = @[@10, @20, @30, @40, @50,@60, @70, @80,@90, @100];
    // 設(shè)置封閉圖形的樣式
    LCView.type = QuadrilateralType;
    self.LCView = LCView;
    LCView.isShowLine = YES;
    [LCView drawChartWithLineChart];
    [self.topView addSubview:LCView];
  • 然后在接收數(shù)據(jù)的時(shí)候,調(diào)用實(shí)施更新的方法:
// 把點(diǎn)加入到數(shù)組中
CGPoint point = CGPointMake(x, y);
NSValue *pointObj = [NSValue valueWithCGPoint:point];
 [weakSelf.LCView.pointArray addObject:pointObj];
            for (int i = 0; i < weakSelf.LCView.pointArray.count; i ++) {
                         NSValue *pointObj = weakSelf.LCView.pointArray[i];
                         CGPoint pointRestored = [pointObj CGPointValue];
                         
                         // 如果 X 軸數(shù)值大于,X 軸會(huì)自動(dòng)往后移動(dòng)
                         if (x > weakSelf.LCView.xValues.count) {
                             // 移除沒有展示出來的點(diǎn),不然數(shù)組里存放的太多了,內(nèi)容會(huì)爆棚
                             if (pointRestored.x < (x - weakSelf.LCView.xValues.count) ) {
                                 [weakSelf.LCView.pointArray removeObject:pointObj];
                             }
                         }
                     }
                     // 調(diào)用實(shí)時(shí)更新折線圖的方法
                     [weakSelf.LCView exchangeLineAnyTime];
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 說明: 已將折線圖封裝到了一個(gè)UIView子類中,并提供了相應(yīng)的接口。若你遇到相應(yīng)的需求可以直接將文件拖到項(xiàng)目中,...
    AHLQ閱讀 7,656評(píng)論 5 47
  • 轉(zhuǎn)載:http://www.itdecent.cn/p/32fcadd12108 每個(gè)UIView有一個(gè)伙伴稱為l...
    F麥子閱讀 6,595評(píng)論 0 13
  • 218.241.181.202 wxhl60 123456 192.168.10.253 wxhl66 wxhl6...
    CYC666閱讀 1,556評(píng)論 0 6
  • 1.iOS中的round、ceil、floor函數(shù)略解 round如果參數(shù)是小數(shù),則求本身的四舍五入.ceil如果...
    K_Gopher閱讀 1,266評(píng)論 1 0
  • 杭州的四月天 有清涼的風(fēng)拂面 是時(shí)候 酒一壺 月下獨(dú)酌 奈何下著雨的夜 如何舉杯邀明月 對(duì)影成三人 明月在我心 依...
    杜香蘭若閱讀 625評(píng)論 8 6

友情鏈接更多精彩內(nèi)容