iOS 개발 의 Quartz2D 소개 및 사용 상세 설명

19448 단어 iosquartz2d
머리말
Quartz2D 의 API 는 순수 C 언어 로 2 차원 그래 픽 엔진 으로 iOS 와 Mac 시스템 을 지원 합 니 다.Quartz2D 의 API 는 Core Graphics 프레임 워 크 에서 나 왔 으 며 데이터 형식 과 함 수 는 기본적으로 CG 를 접두사 로 한다.일반적으로,우 리 는 시스템 이 제공 하 는 컨트롤 을 사용 하여 대부분의 UI 를 완성 할 수 있 지만,일부 UI 인터페이스 는 매우 복잡 하고 개성화 되 어 있 으 며,일반적인 UI 컨트롤 로 는 실현 할 수 없 으 며,이 때 는 Quartz2D 기술 을 이용 하여 컨트롤 내부 의 구 조 를 사용자 정의 컨트롤 과 유사 하 게 그 릴 수 있다.사실 iOS 의 대부분 컨트롤 의 내용 은 Quartz2D 를 통 해 그 려 진 것 이기 때문에 Quartz2D 는 iOS 개발 에서 매우 중요 한 가 치 는 사용자 정의 view(사용자 정의 UI 컨트롤)이다.
Quartz 2D 가 완성 할 수 있 는 작업:
  • 도형 그리 기:선\삼각형\사각형\원\호 등;
  • 텍스트 그리 기;
  • 그림 그리 기\그림 생 성(그림);
  • 읽 기\PDF 생 성;
  • 캡 처\그림 자 르 기;
  • 사용자 정의 UI 컨트롤;
  • … …
  • 2.도형 문맥(Graphics Context)
    그래 픽 컨 텍스트(Graphics Context):CGContextRef 형식의 데이터 입 니 다.
    그래 픽 컨 텍스트 의 역할:
    (1)그림 정보,그림 상태 저장
    (2)출력 목 표를 결정 합 니 다.(어디로 그립 니까?)
    (출력 대상 은 PDF 파일,Bitmap 또는 모니터 의 창 일 수 있 습 니 다)

    같은 그림 시퀀스 로 서로 다른 Graphics Context 를 지정 하면 같은 그림 을 다른 목표 에 그 릴 수 있 습 니 다.
    Quartz2D 는 다음 과 같은 몇 가지 유형의 Graphics Context 를 제공 합 니 다.
    (1)Bitmap Graphics Context
    (2)PDF Graphics Context
    (3)Window Graphics Context
    (4)Layer Graphics Context
    (5)Printer Graphics Context

    현재 컨 텍스트 copy 1 부 를 스 택 꼭대기 에 저장 합 니 다(그 스 택 은'그래 픽 컨 텍스트 스 택'이 라 고 합 니 다).
    
    void CGContextSaveGState(CGContextRef c)
    스 택 상단 의 컨 텍스트 를 스 택 에서 내 보 내 고 현재 컨 텍스트 를 바 꿉 니 다(비우 기 전에 컨 텍스트 설정).
    
    void CGContextRestoreGState(CGContextRef c)
    3.Quartz2D 사용자 정의 View 사용
    1.Quartz2D 사용자 정의 뷰
    어떻게 Quartz2D 사용자 정의 view 를 이용 합 니까?사용자 정의 UI 컨트롤)Quartz2D 를 이용 하여 view 에 물건 을 그 리 는 방법 은 무엇 입 니까?
    우선 그림 정 보 를 저장 하고 어디 에 그 릴 지 결정 할 수 있 기 때문에 그래 픽 컨 텍스트 가 있어 야 합 니 다.
    그 다음 에 그 도형 상하 문 은 view 와 연결 되 어야 내용 을 view 위 에 그 릴 수 있 습 니 다.
    사용자 정의 view 단계:
    (1)새로운 클래스,UIView 계승
    (2)- (void)drawRect:(CGRect)rect 방법 을 실현 한 다음 에 이 방법 에서
    (a)현재 view 와 연 결 된 그래 픽 컨 텍스트 가 져 오기
    
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    (b)해당 하 는 도형 내용 그리 기
    예 를 들 어 1/4 원 그리 기(부채 형)
    
    CGContextMoveToPoint(ctx, 100, 100);
     
    CGContextAddLineToPoint(ctx, 100, 150);
     
    CGContextAddArc(ctx, 100, 100, 50, -M_PI_2, M_PI, 1);
     
    CGContextClosePath(ctx);
     
     
    [[UIColor redColor] set];
    (3)그림 컨 텍스트 를 이용 하여 그 려 진 모든 내용 을 view 에 렌 더 링 합 니 다.
    
    CGContextFillPath(ctx);
    주:
    
    //M_PI   :π
    //M_PI * 2   :2π
     
    //M_PI_2   :π/2
    //M_PI / 2   :π/2
     
    //       
    //bezierPathWithArcCenter:      
    //radius:    
    //startAngle:    ,      0 
    //endAngle:    ,    ,    .
    //clockwise:     ,yes:    no:   
    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:self.center radius:radius startAngle:startA endAngle:endA clockwise:NO];
    전체 코드:
    
    //
    // MyView.m
    // Quartz2DTest
    //
    // Created by     on 2017/2/6.
    // Copyright © 2017     . All rights reserved.
    //
     
    #import "MyView.h"
     
    @implementation MyView
     
    - (instancetype)initWithFrame:(CGRect)frame
    {
     self = [super initWithFrame:frame];
     if (self) {
     self.backgroundColor = [UIColor whiteColor];//       ,            
     }
     return self;
    }
     
     
    - (void)drawRect:(CGRect)rect {
     
     CGContextRef ctx = UIGraphicsGetCurrentContext();
     
     CGContextMoveToPoint(ctx, 100, 100);
     CGContextAddLineToPoint(ctx, 100, 150);
     CGContextAddArc(ctx, 100, 100, 50, -M_PI_2, M_PI, 1);
     CGContextClosePath(ctx);
     
     [[UIColor redColor] set];
     
     CGContextFillPath(ctx);
     
    }
     
    @end
    실행 효과:

    2.핵심 방법 drawRect:
    왜 drawRect 를 실현 해 야 view 에 그림 을 그 릴 수 있 습 니까?
    drawRect:방법 에서 view 와 연 결 된 그래 픽 컨 텍스트 를 얻 을 수 있 기 때 문 입 니 다.
    draw Rect:방법 은 언제 호출 됩 니까?
    view 가 화면 에 처음 표 시 될 때(UIWindow 에 추가 되 어 표 시 됨)
    view 의 setNeeds Display 나 setNeeds DisplayInRect 를 호출 할 때.
    주의 4 시:
  • 은 drawRect:방법 을 수 동 으로 호출 하여 View 와 연 결 된 컨 텍스트 를 자동 으로 만 들 지 않 습 니 다.setNeeds Display 방법 을 호출 해 야 합 니 다.시스템 바 텀 은 drawRect 를 자동 으로 호출 하여 시스템 에 View 를 다시 그립 니 다.그러면 시스템 바 텀 은 View 와 연 결 된 컨 텍스트
  • 을 자동 으로 만 듭 니 다.
  • setNeeds Display 바 텀 에서 drawRect 를 호출 합 니 다.바로 호출 된 것 이 아 닙 니 다.호출 된 플래그 만 설정 되 어 있 습 니 다.호출 시간 은 다음 화면 이 새로 고침 될 때 까지 drawRect 를 호출 합 니 다.화면 이 1 초 에 30-60 초 씩 갱신 되 기 때문에 1 초 에 drawRect 방법 을 30-60 회 호출 합 니 다.속도 가 매우 빠 릅 니 다.
  • view 내부 에 layer(그림)속성 이 있 습 니 다.drawRect:방법 에서 얻 은 것 은 Layer Graphics Context 입 니 다.따라서 그 려 진 것 은 view 의 layer 에 그 려 진 것 입 니 다.
  • View 가 물건 을 표시 할 수 있 는 이 유 는 그 내부 의 layer
  • 때문이다.
    3.Quartz2D 그림 그리 기 코드 절차
    첫 번 째 단계:그림 상하 문 가 져 오기:
    
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    두 번 째 단계:연결 경로(아래 코드 는 라인 을 그립 니 다):
    
    CGContextMoveToPoint(ctx, 10, 10);
    CGContextAddLineToPoint(ctx, 100, 100);
    세 번 째 단계:경로 그리 기:
    
    CGContextStrokePath(ctx); // CGContextFillPath(ctx);
    4.Quartz2D 중요 함수
    1.상용 연결 경로 함수
    새 시작 점
    
    void CGContextMoveToPoint(CGContextRef c, CGFloat x, CGFloat y)
    어떤 점 에 새 선분 을 추가 합 니 다.
    
    void CGContextAddLineToPoint(CGContextRef c, CGFloat x, CGFloat y)
    사각형 추가
    
    void CGContextAddRect(CGContextRef c, CGRect rect)
    타원 추가
    
    void CGContextAddEllipseInRect(CGContextRef context, CGRect rect)
    원호 추가
    
    void CGContextAddArc(CGContextRef c, CGFloat x, CGFloat y,
     
    CGFloat radius, CGFloat startAngle, CGFloat endAngle, int clockwise)
    2.경로 함수 그리 기
    보통 CGContextDraw,CGContextStroke,CGContextFill 로 시작 하 는 함수 로 경 로 를 그립 니 다.
    Mode 매개 변 수 는 그리 기 모드 를 결정 합 니 다.
    
    void CGContextDrawPath(CGContextRef c, CGPathDrawingMode mode)
    중 공 경로 그리 기
    
    void CGContextStrokePath(CGContextRef c)
    옹 골 진 경로 그리 기
    
    void CGContextFillPath(CGContextRef c)
    3.매트릭스 조작 함수
    행렬 을 이용 하여 상하 문 에 그 려 진 모든 경 로 를 함께 변화 시 킬 수 있 습 니 다.
    크기 조정:
    
    void CGContextScaleCTM(CGContextRef c, CGFloat sx, CGFloat sy)
    회전:
    
    void CGContextRotateCTM(CGContextRef c, CGFloat angle)
    이동:
    
    void CGContextTranslateCTM(CGContextRef c, CGFloat tx, CGFloat ty)
    4.기타 상용 함수
    선분 너비 설정
    
    CGContextSetLineWidth(ctx, 10);
    선분 머리 끝의 스타일 을 설정 합 니 다.
    
    CGContextSetLineCap(ctx, kCGLineCapRound);
    선분 전환점 설정 스타일
    
    CGContextSetLineJoin(ctx, kCGLineJoinRound);
    색상 설정
    
    CGContextSetRGBStrokeColor(ctx, 1, 0, 0, 1);
    5.Quartz2D 의 메모리 관리
    Quartz2D 메모리 관리 에 대해 다음 과 같은 원칙 이 있 습 니 다.
    (1)"Create"또는"Copy"가 함 유 된 함 수 를 사용 하여 만 든 대상 은 사용 후 방출 해 야 하 며 그렇지 않 으 면 메모리 가 유출 될 수 있 습 니 다.
    (2)"Create"또는"Copy"가 없 는 함수 로 가 져 온 대상 을 사용 하면 풀 필요 가 없습니다.
    (3)리 테 인 먼 트 대상 이 있 으 면 더 이상 사용 하지 않 을 때 릴 리 스 를 해 야 합 니 다.
    (4)Quartz 2D 함 수 를 사용 하여 retain 과 release 의 대상 을 지정 할 수 있 습 니 다.예 를 들 어 CGColorSpace 대상 을 만 들 면 함수 CGColorSpace Retain 과 CGColorSpace Release 를 사용 하여 retain 과 release 대상 을 유지 합 니 다.
    (5)코어 재단 의 CFRetain 과 CFRelease 도 사용 할 수 있다.이 함수 들 에 NULL 값 을 전달 할 수 없 도록 주의 하 세 요.
    6.Quartz2D 사용 사례
    1.직사각형,정사각형 그리 기
    
    - (void)drawRect:(CGRect)rect {
     
     //1.     
     CGContextRef ctx = UIGraphicsGetCurrentContext();
     //2.    
     UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(50, 50, 200, 200)];
     //3.         
     CGContextAddPath(ctx, path.CGPath);
     
     [[UIColor redColor] set];//      
     
     //4.          View layer.
     //CGContextStrokePath(ctx);//     
     CGContextFillPath(ctx);//     
     
    }
    실행 효과:

    2.부채꼴 그리 기
    위의'2.Quartz2D 사용자 정의 View'중의 방법 을 제외 하고 OC 에서 자체 적 으로 그림 을 그 리 는 방법 으로 도 실현 할 수 있 습 니 다.다음 과 같 습 니 다.
    
    - (void)drawRect:(CGRect)rect {
     
     CGPoint center = CGPointMake(rect.size.width * 0.5, rect.size.height * 0.5);
     CGFloat radius = rect.size.width * 0.5 - 10;
     CGFloat startA = 0;
     CGFloat endA = -M_PI_2;
     //      
     UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:startA endAngle:endA clockwise:NO];
     //         
     [path addLineToPoint:center];
     //     
     [path closePath];
     //     
     [[UIColor redColor] set];
     //     
     [path fill];
     //     
     //[path stroke];
     
    }
    실행 효과:

    주:
    하나의 점 이 직사각형 상자 안에 있 는 지 판단 하 다.
    
    CGRectContainsPoint(rect,point);//  point      rect      
    3.원형 그리 기
    
    - (void)drawRect:(CGRect)rect {
     
     //1.     
     CGContextRef ctx = UIGraphicsGetCurrentContext();
     //2.    
     // cornerRadius:    。       200,     100,                        100,     
     UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(50, 50, 200, 200) cornerRadius:100];
     //3.         
     CGContextAddPath(ctx, path.CGPath);
     
     [[UIColor redColor] set];//      
     
     //4.          View layer.
     // CGContextStrokePath(ctx);//     
     CGContextFillPath(ctx);//     
     
    }
    실행 효과:

    4.원 각 사각형 그리 기
    
    - (void)drawRect:(CGRect)rect {
     
     //1.     
     CGContextRef ctx = UIGraphicsGetCurrentContext();
     //2.    
     // cornerRadius:    。
     UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(50, 50, 200, 200) cornerRadius:50];
     //3.         
     CGContextAddPath(ctx, path.CGPath);
     
     [[UIColor redColor] set];//      
     
     //4.          View layer.
     CGContextStrokePath(ctx);//     
     //CGContextFillPath(ctx);//     
     
    }
    실행 효과:

    5.직선 그리 기
    
    - (void)drawRect:(CGRect)rect {
     
     //1.   View       (uigraphics  )
     CGContextRef ctx = UIGraphicsGetCurrentContext();
     
     //2.    
     //              :path         :path     (2       ),          
     UIBezierPath *path = [UIBezierPath bezierPath];
     //    
     [path moveToPoint:CGPointMake(50, 150)];
     //     Line    
     [path addLineToPoint:CGPointMake(250, 50)];
     
     //     
     [path moveToPoint:CGPointMake(50, 250)];
     [path addLineToPoint:CGPointMake(250, 100)];
     
     //    
     CGContextSetLineWidth(ctx, 20);
     //        
     CGContextSetLineJoin(ctx, kCGLineJoinBevel);
     //        
     CGContextSetLineCap(ctx, kCGLineCapRound);//     
     //      
     [[UIColor redColor] set];
     
     //3.         
     CGContextAddPath(ctx, path.CGPath);
     //4.               View   layer
     CGContextStrokePath(ctx);
     
    }
    실행 효과:

    6.곡선 그리 기
    벤 젤 곡선 원리:
    
    - (void)drawRect:(CGRect)rect {
     
     //1.   View       .】
     CGContextRef ctx = UIGraphicsGetCurrentContext();
     //2.    
     UIBezierPath *path = [UIBezierPath bezierPath];
     //   ,    .       (              )
     //    
     [path moveToPoint:CGPointMake(10, 150)];
     //          
     [path addQuadCurveToPoint:CGPointMake(200, 150) controlPoint:CGPointMake(150, 10)];
     //3.           
     CGContextAddPath(ctx, path.CGPath);
     //4.         View 
     CGContextStrokePath(ctx);
     
    }
    실행 효과:

    7.떡 그림 그리 기
    방법 1:
    
    - (void)drawRect:(CGRect)rect {
     
     NSArray *dataArray = @[@25,@25,@50];
     //   
     CGPoint center = CGPointMake(rect.size.width * 0.5, rect.size.height * 0.5);
     //   
     CGFloat radius = rect.size.width * 0.5 - 10;
     
     CGFloat startA = 0;
     CGFloat angle = 0;
     CGFloat endA = 0;
     
     for (NSNumber *num in dataArray) {
      startA = endA;
      //         25,angle =25/100 *2π, angle = π/2,   1/4 ,
      angle = num.intValue / 100.0 * M_PI * 2;
      //     =      +                
      endA = startA + angle;
      //          
      UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:startA endAngle:endA clockwise:YES];
      //       
      [[self randomColor] set];
      //         
      [path addLineToPoint:center];
      //     
      [path fill];
      //     
    //  [path stroke];
     }
     
    }
     
     
    /**
           
     
     @return UIColor
     */
    -(UIColor *)randomColor{
     
     CGFloat redLevel = rand() / (float) RAND_MAX;
     CGFloat greenLevel = rand() / (float) RAND_MAX;
     CGFloat blueLevel = rand() / (float) RAND_MAX;
     
     return [UIColor colorWithRed: redLevel green: greenLevel blue: blueLevel alpha: 1.0];
    }
    실행 효과:

    방법 2:
    
    - (void)drawRect:(CGRect)rect {
     
     CGPoint center = CGPointMake(self.bounds.size.width * 0.5, self.bounds.size.height * .5);
     CGFloat radius = self.bounds.size.width * 0.5 - 10;
     CGFloat startA = 0;
     CGFloat endA = 25 / 100.0 * M_PI * 2;
     UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:startA endAngle:endA clockwise:YES];
     [[UIColor redColor] set];
     //        
     [path addLineToPoint:center];
     [path fill];
     
     //     
     startA = endA;
     CGFloat angle = 25 / 100.0 * M_PI * 2;
     endA = startA + angle;
     UIBezierPath *path2 = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:startA endAngle:endA clockwise:YES];
     [[UIColor greenColor] set];
     //        
     [path2 addLineToPoint:center];
     [path2 fill];
     
     startA = endA;
     angle = 50 / 100.0 * M_PI * 2;
     endA = startA + angle;
     UIBezierPath *path3 = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:startA endAngle:endA clockwise:YES];
     [[UIColor blueColor] set];
     //        
     [path3 addLineToPoint:center];
     [path3 fill];
     
    }
     
     
    /**
           
     
     @return UIColor
     */
    -(UIColor *)randomColor{
     
     CGFloat redLevel = rand() / (float) RAND_MAX;
     CGFloat greenLevel = rand() / (float) RAND_MAX;
     CGFloat blueLevel = rand() / (float) RAND_MAX;
     
     return [UIColor colorWithRed: redLevel green: greenLevel blue: blueLevel alpha: 1.0];
    }
    주:
    아래 를 클릭 하여 색상 을 바 꾸 려 면 다음 코드 를 추가 할 수 있 습 니 다.
    
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
     
     //  
     [self setNeedsDisplay];
     
    }
    8.텍스트 그리 기
    
    - (void)drawRect:(CGRect)rect {
     
     NSString *str = @"     :http://www.imlifengfeng.com/";
     
     NSMutableDictionary *dict = [NSMutableDictionary dictionary];
     //    
     dict[NSFontAttributeName] = [UIFont systemFontOfSize:30];
     //    
     dict[NSForegroundColorAttributeName] = [UIColor redColor];
     //    
     dict[NSStrokeColorAttributeName] = [UIColor blueColor];
     dict[NSStrokeWidthAttributeName] = @3;
     //    
     NSShadow *shadow = [[NSShadow alloc] init];
     shadow.shadowColor = [UIColor greenColor];
     shadow.shadowOffset = CGSizeMake(-2, -2);
     shadow.shadowBlurRadius = 3;
     dict[NSShadowAttributeName] = shadow;
     
     //       
     //drawAtPoint      
     //[str drawAtPoint:CGPointMake(0, 0) withAttributes:dict];
     //drawInRect     
     [str drawInRect:self.bounds withAttributes:dict];
     
    }
    실행 효과:

    9.워 터 마크 추가
    
    //
    // ViewController.m
    // Quartz2DTest
    //
    // Created by     on 2017/2/6.
    // Copyright © 2017     . All rights reserved.
    //
     
    #import "ViewController.h"
    #import "MyView.h"
     
    @interface ViewController ()
     
    @end
     
    @implementation ViewController
     
    - (void)viewDidLoad {
     [super viewDidLoad];
     
     UIImageView *myImageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)];
     [self.view addSubview:myImageView];
     
     
     //      
     //0.    
     UIImage *oriImage = [UIImage imageNamed:@"test"];
     //1.       (size:        ,         )
     UIGraphicsBeginImageContext(oriImage.size);
     //2.           
     [oriImage drawAtPoint:CGPointZero];
     //3.    (  UILabel          ,           )
     NSString *str = @"     ";
     
     
     NSMutableDictionary *dict = [NSMutableDictionary dictionary];
     dict[NSFontAttributeName] = [UIFont systemFontOfSize:20];
     dict[NSForegroundColorAttributeName] = [UIColor redColor];
     
     [str drawAtPoint:CGPointZero withAttributes:dict];
     //4.            
     UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
     //5.       
     UIGraphicsEndImageContext();
     
     
     myImageView.image = newImage;
     
    }
     
    @end
    실행 효과:

    10.화면 캡 처
    
    -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
     
     //    
     //1.         
     UIGraphicsBeginImageContext(self.view.bounds.size);
     //2. View           
     CGContextRef ctx = UIGraphicsGetCurrentContext();
     //UIView            ,          
     [self.view.layer renderInContext:ctx];
     //3.            
     UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
     //4.     
     UIGraphicsEndImageContext();
     //         
     //NSData *data = UIImageJPEGRepresentation(newImage, 1);
     NSData *data = UIImagePNGRepresentation(newImage);
     
     [data writeToFile:@"/Users/lifengfeng/Downloads/imlifengfeng.jpg" atomically:YES];
     
    }
    실행 효과:
    캡 처 일 뿐 이 야.그냥 캡 처 하 는 것 처럼 직접 해 봐.
    총결산
    이상 은 바로 Quartz2D 에 관 한 자주 사용 하 는 사례 로 Quartz2D 는 더 많은 효 과 를 실현 할 수 있 고 구체 적 인 수요 에 따라 실현 할 수 있다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.

    좋은 웹페이지 즐겨찾기