如何在iPhone上绘制出一个笑脸

下面的笑脸这就是今天我们要画的图 。

我们应该如何使用iPhone进行绘图,iPhone的绘图是在UIVIew的drawRect方法中实现的。如果我们要在UIView绘制图呢,就要写一个UIVIew的扩展类,并重写drawRect方法。那么程序执行的时候,会调用此方法进行绘制。


比如,现在我们要绘制一个笑脸,在 drawRect 实现的代码如下,我将整个文件代码都贴上:

FaceView.h

//
//  FaceView.h
//  Happiness
//
//  Created by surfboy on 1/30/13.
//  Copyright (c) 2013 SurfBoy. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface FaceView : UIView

@end


FaceView.m

//
//  FaceView.m
//  Happiness
//
//  Created by surfboy on 1/30/13.
//  Copyright (c) 2013 SurfBoy. All rights reserved.
//

#import "FaceView.h"

@implementation FaceView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self setup];
    }
    return self;
}

- (void)awakeFromNib {
    
    [self setup];
}

- (void)setup {
    
    self.contentMode = UIViewContentModeRedraw;
}


// 画圆
- (void)drawCircleAtPoint:(CGPoint)p withRadius:(CGFloat)radius inContext:(CGContextRef)context {
    
    // UIGraphicsPushContext UIGraphicsPopContext 保证不破坏调用程序的Context
    UIGraphicsPushContext(context);

    // 创建一个路径
    CGContextBeginPath(context);

    // 调用画圆的方法
    CGContextAddArc(context, p.x, p.y, radius, 0, 2*M_PI, YES);

    // 开始画路径
    CGContextStrokePath(context);

    // 弹出当前的Context
    UIGraphicsPopContext();
}


#define DEFAULT_SCALE 0.9

#define DEFAULT_EYE_RADIUS 0.1
#define DEFAULT_EYE_H 0.35
#define DEFAULT_EYE_V 0.35

#define DEFAULT_MOUTH_H 0.45
#define DEFAULT_MOUTH_V 0.45
#define DEFAULT_MOUTH_SMILE 0.3

// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
    // 取得当前上下文
    CGContextRef context = UIGraphicsGetCurrentContext();

    // 计算出屏幕中心的点x,y
    CGPoint midPoint;
    midPoint.x = self.bounds.origin.x + self.bounds.size.width / 2;
    midPoint.y = self.bounds.origin.y + self.bounds.size.height /2;
    
    // 计算出圆的半径,为了留点边距 * DEFAULT_SCALE
    CGFloat size = self.bounds.size.width /2;

    // 旋转屏幕的时高与宽对调
    if (self.bounds.size.height < self.bounds.size.width) size = self.bounds.size.height / 2;

    // 按比例缩小,留出边距
    size *= DEFAULT_SCALE;

    // 设置线的宽
    CGContextSetLineWidth(context, 5.0);

    // 颜色
    [[UIColor blueColor] setStroke];
    
    // 开始画圆
    [self drawCircleAtPoint:midPoint withRadius:size inContext:context];
    
    // *开始画第一只眼睛,定位主要靠midPoint为基点
    CGPoint eyePoint;
    eyePoint.x = midPoint.x - size * DEFAULT_EYE_H;
    eyePoint.y = midPoint.y - size * DEFAULT_EYE_V;
    [self drawCircleAtPoint:eyePoint withRadius:size * DEFAULT_EYE_RADIUS inContext:context];
    
    // 第二只眼睛
    eyePoint.x += size * DEFAULT_EYE_H * 2;
    [self drawCircleAtPoint:eyePoint withRadius:size * DEFAULT_EYE_RADIUS inContext:context];
    
    // *开始画嘴,定义第一个点 // http://www.xushao.net/2013/01/31/3944 
    CGPoint mouthStart;
    mouthStart.x = midPoint.x - size * DEFAULT_MOUTH_H;
    mouthStart.y = midPoint.y + size * DEFAULT_MOUTH_V;
    
    // 结速的点
    CGPoint mouthEnd = mouthStart;
    mouthEnd.x += DEFAULT_MOUTH_V * size * 2;
    
    // Curve Point1
    CGPoint mouthCP1 = mouthStart;
    mouthCP1.x += DEFAULT_MOUTH_H *size * 2 / 3;
    
    // Curve Point2
    CGPoint mouthCP2 = mouthEnd;
    mouthCP2.x -= DEFAULT_MOUTH_H * size * 2 / 3;
    
    // 笑容指数
    float smile = 1;
    
    // DEFAULT_MOUTH_SMILE 越高,笑得越开
    CGFloat smileOffset = DEFAULT_MOUTH_SMILE * size * smile;
    mouthCP1.y += smileOffset;
    mouthCP2.y += smileOffset;
    
    CGContextBeginPath(context);
    CGContextMoveToPoint(context, mouthStart.x, mouthStart.y);
    CGContextAddCurveToPoint(context, mouthCP1.x, mouthCP1.y, mouthCP2.x, mouthCP2.y, mouthEnd.x, mouthEnd.y);
    CGContextStrokePath(context);
    
}


@end

以上的代码,我都做了一个详细的注解说明,至于调用方法的详细参数说明和用法请查看官网文档,它已经写得很清楚了。

说明一下,绘制和重绘都是在drawRect中完成,但我们一般不直接调用 drawRect,苹果也不建议我们这么干。苹果要求我们使用 UIView 中的 setNeedsDisplay方法,这个方法程序会自动调用drawRect进行绘制。

上面的代码,主要的思路很简单。计算出中心点 midPoint ,size *DEFAULT_SCALE 是为了圆与屏幕保留一定的距离。然后下面的眼、嘴都是按照midPoint、size为基数进行计算。稍微有点难理解的就是画嘴,因为它可以笑也可以不开心,不明白的可以看注解的地址,很清析说明。

在我们旋转设备的时候,你会发现,表情图不会重绘?而是被拉长了。只要我们设置 self.contentMode = UIViewContentModeRedraw; 当设置或者iframe发生改变的时候,都会自动调用 drawRect。我新建了一个方法setup,然后分别在 awakeFromNib、initWithFrame 调用。


完整的源码下载:iOS SDK 6.1 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值