* Quartz 라이브러리
- 아이폰 OS에서 그래픽 기능을 구현하기 위한 C 라이브러리
- 그림을 그리기 위해서는 그림을 그릴 대상인 CGContextRef가 필요하다. 그림을 그리기 위한 모든 정보를 저장하는 컨텍스트임. 그래픽카드를 추상화한 개념이라고 생각하면 된다
view : drawRect( ) -> CGContextRef에서 상속받음
- Quartz API를 이용해 객체를 생성, 뷰가 아닌 다른 곳에 그림을 그릴 수 있다
- 뷰에 그림을 그리기 위해서는 drawRect 메소드를 이용해서
CGContextRef 변수명 = UIGraphicsGetCurrentContext();
와 같이 해주면 변수명이 CGContextRef 객체가 된다.
- touchesBegan 등에서도 그릴 수는 있다. 다만 CGContextRef가 없기 때문에 drawRect()를 빌려서 사용해야 한다
* drawRect
- 다음과 같은 경우에 자동으로 호출된다
뷰 위를 부분적으로 덮고 있던 또 다른 뷰가 이동하거나 사라질때
숨겨져 있던 뷰의 hidden 속성을 NO로 설정해서 다시 나타나도록 했을 때
뷰를 스크린 밖으로 스크롤했다가 돌아올때
setNeedsDisplay나 setNeedsDisplayInRect를 호출했을 때
- 패러미터
CGContextSetRGBStrokeColor(그래픽컨텍스트,R,G,B,A):선의 색상
CGContextSetLineWidth(그래픽컨텍스트, 두께)
CGContextStrokePath(그래픽 컨텍스트)
CGContextSetRGBFillColor(그래픽컨텍스트,R,G,B,A): 면색
* 작도 함수
- 선 그리기
CGContextMoveToPoint(그래픽컨텍스트객체, x, y)
CGContextAddLineToPoint(그래픽컨텍스트객체, x, y) : 계속해서 이어서 그린다
CGContextSetLineDash(그래픽컨텍스트객체, 시작위치, 실수배열, 개수);
- 사각형 그리기
CGContextFillRect(그래픽컨텍스트객체, CGRect 타입 변수)
- 원 그리기
CGContextAddEllipseInRect(그래픽컨텍스트객체, CGRect 타입 변수)
- 다각형은 선을 연속해서 그리면 됨
* 선 그리는 예제 코드(TestView.m)
#import "TestView.h"
@implementation TestView
- (id)initWithFrame:(CGRect)frame
{
if ((self = [super initWithFrame:frame]))
{
// Initialization code
}
return self;
}
-(IBAction)Line
{
mode = 1;
[self setNeedsDisplay];
}
-(IBAction)Rect
{
mode = 2;
[self setNeedsDisplay];
}
-(IBAction)Polygon
{
mode = 3;
[self setNeedsDisplay];
}
-(void) drawLine:(CGContextRef)context
{
// 선 색상 설정
CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0);
// 선 두께
CGContextSetLineWidth(context, 1.0);
// 선 그리기
CGContextMoveToPoint(context, 10.0, 30.0);
CGContextAddLineToPoint(context, 310.0, 30.0);
CGContextStrokePath(context);
CGContextSetLineWidth(context, 1.0);
// 두번째 선
CGContextSetLineWidth(context, 4.0);
CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 1.0);
CGContextMoveToPoint(context, 10.0, 50.0);
CGContextAddLineToPoint(context, 310.0, 50.0);
CGContextStrokePath(context);
// 점선
CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0);
CGFloat dash[] = {5.0, 10.0, 15.0, 20.0};
CGContextSetLineDash(context, 0.0, dash, 4);
CGContextMoveToPoint(context, 10.0, 70.0);
CGContextAddLineToPoint(context, 310.0, 70.0);
CGContextStrokePath(context);
CGContextSetLineDash(context, 0.0, NULL, 0); // 점선을 그리게 해주는 방법
// 배열 이용하기
CGPoint lines[] =
{
CGPointMake(10.0, 90.0),
CGPointMake(60.0, 140.0),
CGPointMake(110.0, 130.0),
CGPointMake(160.0, 190.0),
CGPointMake(210.0, 200.0),
CGPointMake(260.0, 90.0),
CGPointMake(310.0, 200.0),
};
CGContextSetLineWidth(context, 5.0);
CGContextAddLines(context, lines, sizeof(lines)/sizeof(lines[0])); // 배열의 갯수 구하는 방법이지만
// 포인터 배열에서는 사용하지 말 것.
CGContextStrokePath(context);
}
-(void) drawRectangle:(CGContextRef)context
{
// 선 색상
CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0);
// 채우기 색
CGContextSetRGBFillColor(context, 0.0, 1.0, 0.0, 1.0);
// 선 두께
CGContextSetLineWidth(context, 2.0);
// 경로에 사각형 추가
CGContextAddRect(context, CGRectMake(30.0, 30.0, 60.0, 60.0));
CGContextStrokePath(context);
// 사각형 채우기
CGContextFillRect(context, CGRectMake(130.0, 30.0, 60.0, 60.0));
CGContextStrokeRectWithWidth(context, CGRectMake(230.0, 30.0, 60.0, 60.0), 4.0);
}
-(void) drawPolygon:(CGContextRef)context
{
CGPoint center;
// 선 색상
CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0);
// 채우기 색
CGContextSetRGBFillColor(context, 1.0, 0.0, 0.0, 1.0);
// 선 두께
CGContextSetLineWidth(context, 1.0);
// 별 그리기
center = CGPointMake(80.0, 100.0);
CGContextMoveToPoint(context, center.x, center.y + 30.0);
for(int i = 1; i < 5; ++i)
{
CGFloat x = 30.0 * sinf(i * 4.0 * M_PI / 5.0); // M_PI -> Objective-C에서 매크로로 정의해둔
// 원주율 값
CGFloat y = 30.0 * cosf(i * 4.0 * M_PI / 5.0);
CGContextAddLineToPoint(context, center.x + x, center.y + y);
}
CGContextClosePath(context);
CGContextFillPath(context);
// 별 + 원 그리기
center = CGPointMake(160.0, 100.0);
CGContextMoveToPoint(context, center.x, center.y + 30.0);
for(int i = 1; i < 5; ++i)
{
CGFloat x = 30.0 * sinf(i * 4.0 * M_PI / 5.0);
CGFloat y = 30.0 * cosf(i * 4.0 * M_PI / 5.0);
CGContextAddLineToPoint(context, center.x + x, center.y + y);
}
CGContextAddEllipseInRect(context,CGRectMake(130, 70, 60,60));
CGContextClosePath(context);
CGContextEOFillPath(context);
// 5각형 그리기
center = CGPointMake(240.0, 100.0);
CGContextMoveToPoint(context, center.x, center.y + 30.0);
for(int i = 1; i < 6; ++i)
{
CGFloat x = 30.0 * sinf(i * 2.0 * M_PI / 6.0);
CGFloat y = 30.0 * cosf(i * 2.0 * M_PI / 6.0);
CGContextAddLineToPoint(context, center.x + x, center.y + y);
}
CGContextClosePath(context);
CGContextDrawPath(context, kCGPathFillStroke);
}
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
if(mode==1)
[self drawLine:context];
else if(mode==2)
[self drawRectangle:context];
else
[self drawPolygon:context];
// Drawing code
}
* 베지어 곡선
- CGContextAddCurveToPoint 를 이용해서 그린다
- 3개의 좌표를 대입하게 되는데 이 좌표는 첫번째 제어점, 두번째 제어점, 종료점이다
1. 앞의 예제에 툴바 버튼을 1개 추가
2. IBAction 메소드 추가하고 앞에 만든 툴바 버튼과 연결
-(IBAction)Bazier;
3. 메소드 구현
-(IBAction)Bazier
{
mode = 4;
[self setNeedsDisplay];
}
-(void) drawBezier:(CGContextRef)context
{
// 색상 설정
CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0);
// 선 두께
CGContextSetLineWidth(context, 2.0);
// 원 그리기 (하단)
CGContextAddEllipseInRect(context,CGRectMake(60, 20, 200,200));
CGContextSetRGBFillColor(context, 0.0, 0.0, 1.0, 1.0);
CGContextDrawPath(context, kCGPathFillStroke);
CGContextStrokePath(context);
// 베지어 곡선 그리기
CGPoint s = CGPointMake(60.0, 120.0);
CGPoint cp1 = CGPointMake(130.0, 230.0);
CGPoint cp2 = CGPointMake(190.0, 10.0);
CGPoint e = CGPointMake(260.0, 120.0);
CGContextMoveToPoint(context, s.x, s.y);
CGContextAddCurveToPoint(context, cp1.x, cp1.y, cp2.x, cp2.y, e.x, e.y);
CGContextSaveGState(context);
// 반원 그리기 (상단)
CGContextAddArc(context,160,120,100,0,M_PI,true);
CGContextSetRGBFillColor(context, 1.0, 0.0, 0.0, 1.0);
CGContextDrawPath(context, kCGPathFillStroke);
CGContextStrokePath(context);
}
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
if(mode==1)
[self drawLine:context];
else if(mode==2)
[self drawRectangle:context];
else if(mode ==3)
[self drawPolygon:context];
else
[self drawBezier:context];
// Drawing code
}
* Core Animation
- 간단 예제
#import <QuartzCore/CAAnimation.h>
#import <QuartzCore/CAMediaTimingFunction.h>
#import "AniTest.h"
@implementation AniTest
-(IBAction)ani1 // 투명도 보
{
CABasicAnimation *ani = [CABasicAnimation animationWithKeyPath:@"opacity"];
float from = 0.1;
float to = 1.0;
ani.fromValue = [NSNumber numberWithFloat:from];
ani.toValue = [NSNumber numberWithFloat:to];
ani.duration = 1.0;
ani.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
ani.delegate = self;
ani.autoreverses = YES;
[imgView.layer addAnimation:ani forKey:nil];
imgView.layer.opacity = 1.0;
}
-(IBAction)ani2 // 위치 보
{
CABasicAnimation *ani = [CABasicAnimation animationWithKeyPath:@"position"];
CGPoint from = CGPointMake(50,50);
CGPoint to = CGPointMake(250,250);
ani.fromValue = [NSValue valueWithCGPoint:from];
ani.toValue = [NSValue valueWithCGPoint:to];
ani.duration = 1.0;
ani.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
ani.delegate = self;
ani.autoreverses = YES;
[imgView.layer addAnimation:ani forKey:nil];
imgView.layer.position = to;
}
-(IBAction)ani3 // 크기 보간
{
CABasicAnimation *ani = [CABasicAnimation animationWithKeyPath:@"bounds"];
CGRect from = imgView.layer.bounds;
CGRect to = CGRectMake(20,20,120,120);
ani.fromValue = [NSValue valueWithCGRect:from];
ani.toValue = [NSValue valueWithCGRect:to];
ani.duration = 1.0;
ani.delegate = self;
ani.autoreverses = YES;
[imgView.layer addAnimation:ani forKey:nil];
}
-(IBAction)ani4 // 키프레임 커브 좌표 보간이동
{
CAKeyframeAnimation *ani = [CAKeyframeAnimation animationWithKeyPath:@"position"];
CGMutablePathRef thePath = CGPathCreateMutable();
CGPathMoveToPoint(thePath,NULL, 50,200);
CGPathAddCurveToPoint(thePath,NULL,
100.0,50.0,
220.0,350.0,
270.0,200.0);
ani.path = thePath;
ani.calculationMode = kCAAnimationPaced;
ani.duration = 3.0;
ani.delegate = self;
[imgView.layer addAnimation:ani forKey:nil];
CFRelease(thePath);
}
- (id)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
// Initialization code
}
return self;
}
'프로그래밍 > Objective-C' 카테고리의 다른 글
중앙정보학원 아이폰과정 18일차 - 2010년 7월 28일 (0) | 2010.07.28 |
---|---|
중앙정보학원 아이폰과정 14일차 - 2010년 7월 22일 (0) | 2010.07.22 |
중앙정보학원 아이폰과정 13일차 - 2010년 7월 21일 (0) | 2010.07.21 |
아이폰 OS 개발 자료 총정리 (0) | 2010.07.20 |
#pragma mark로 코드 쉽게 구분하기 (0) | 2010.07.20 |