你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> iOS開發中Quartz2D控制圓形縮放和實現刷幀效果

iOS開發中Quartz2D控制圓形縮放和實現刷幀效果

編輯:IOS開發綜合

Quartz2D簡要回顧
一、什麼是Quartz2D

 Quartz 2D是⼀個二維繪圖引擎,同時支持iOS和Mac系統

 Quartz 2D能完成的工作:

  繪制圖形 : 線條\三角形\矩形\圓\弧等

  繪制文字

  繪制\生成圖片(圖像)

  讀取\生成PDF

  截圖\裁剪圖片

  自定義UI控件

二、Quartz2D在iOS開發中的價值

為了便於搭建美觀的UI界面,iOS提供了UIKit框架,⾥⾯有各種各樣的UI控件

UILabel:顯⽰文字
UIImageView:顯示圖片
UIButton:同時顯示圖片和⽂字(能點擊)

利⽤UIKit框架提供的控件,拼拼湊湊,能搭建和現實一些簡單、常見的UI界⾯

但是,有些UI界面極其復雜、⽽且⽐較個性化,⽤普通的UI控件無法實現,這時可以利用Quartz2D技術將控件內部的結構畫出來,自定義控件的樣子

其實,iOS中⼤部分控件的內容都是通過Quartz2D畫出來的
因此,Quartz2D在iOS開發中很重要的⼀個價值是:自定義view(自定義UI控件)

三、圖形上下文

圖形上下文(Graphics Context):是一個CGContextRef類型的數據

圖形上下文的作用:

(1)保存繪圖信息、繪圖狀態
(2)決定繪制的輸出目標(繪制到什麼地⽅去?) (輸出目標可以是PDF⽂文件、Bitmap或者顯示器的窗口上)

201512292227373.png (674×129)

相同的⼀套繪圖序列,指定不同的Graphics Context,就可將相同的圖像繪制到不同的目標上

201512292252318.png (719×358)

四、自定義view

如何利用Quartz2D⾃定義view?(⾃定義UI控件)

如何利用Quartz2D繪制東西到view上?

首先,得有圖形上下文,因為它能保存繪圖信息,並且決定著繪制到什麼地方去

其次,那個圖形上下⽂必須跟view相關聯,才能將內容繪制到view上面

⾃定義view的步驟:

(1)新建⼀個類,繼承自UIView

(2)實現-(void)drawRect:(CGRect)rect⽅法.然後在這個⽅方法中 :

1)取得跟當前view相關聯的圖形上下文;

2)繪制相應的圖形內容

3)利用圖形上下文將繪制的所有內容渲染顯示到view上面

五、補充說明

1.drawRect:

(1)為什麼要實現drawRect:⽅法才能繪圖到view上?

因為在drawRect:⽅法中才能取得跟view相關聯的圖形上下文

(2)drawRect:⽅法在什麼時候被調用?

當view第一次顯示到屏幕上時(被加到UIWindow上顯示出來)

調用view的setNeedsDisplay或者setNeedsDisplayInRect:時

 2.Quartz2D須知

  • Quartz2D的API是純C語⾔言的
  • Quartz2D的API來自於Core Graphics框架
  • 數據類型和函數基本都以CG作為前綴
  • CGContextRef
  • CGPathRef
  • CGContextStrokePath(ctx);

 3.drawRect:中取得的上下⽂文

在drawRect:方法中取得上下文後,就可以繪制東西到view上

View內部有個layer(圖層)屬性,drawRect:方法中取得的是一個Layer Graphics Context,因此,繪制的東西其實是繪制到view的layer上去了

View之所以能顯示東西,完全是因為它內部的layer


通過slider控制圓的縮放
1.實現過程

新建一個項目,新建一個繼承自UIview的類,並和storyboard中自定義的view進行關聯。

界面搭建,如圖:

代碼示例:

YYViewController.m文件
復制代碼 代碼如下:
//
//  YYViewController.m
//  04-對圓進行縮放
//
//  Created by apple on 14-6-11.
//  Copyright (c) 2014年 itcase. All rights reserved.
//

#import "YYViewController.h"
#import "YYview.h"

@interface YYViewController ()
@property (weak, nonatomic) IBOutlet YYview *circleView;
- (IBAction)valueChange:(UISlider *)sender;

@end

復制代碼 代碼如下:
@implementation YYViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}


- (IBAction)valueChange:(UISlider *)sender {
    //當值改變的時候,把值傳遞給view,改變圓的半徑
    NSLog(@"%f",sender.value);
    //把sender的值傳遞給自定義view,設置圓的半徑
    self.circleView.radius=sender.value;
}
@end

YYview.h文件
復制代碼 代碼如下:
//
//  YYview.h
//  04-對圓進行縮放
//
//  Created by apple on 14-6-11.
//  Copyright (c) 2014年 itcase. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface YYview : UIView
//提供一個屬性來接收外界傳入的半徑
@property(nonatomic,assign)float radius;
@end

YYview.m文件
復制代碼 代碼如下:
//
//  YYview.m
//  04-對圓進行縮放
//
//  Created by apple on 14-6-11.
//  Copyright (c) 2014年 itcase. All rights reserved.
//

#import "YYview.h"

@implementation YYview
//自定義view中的圓不顯示
//重寫set方法,為半徑賦值
-(void)setRadius:(float)radius
{
    _radius=radius;
    //通知自定義的view重新繪制圖形
    [self setNeedsDisplay];
}

//如果view是從xib或storyboard中創建出來的會先調用awakefromnib方法
- (void)awakeFromNib
{
    //在這裡為圓的半徑設定一個初始的值
    self.radius = 20;
}

- (void)drawRect:(CGRect)rect
{
    //1.獲取圖形上下文
    CGContextRef ctx=UIGraphicsGetCurrentContext();
    //2.繪圖
    //在自定義的view中畫一個圓
    CGContextAddArc(ctx, 100, 100, self.radius, 0, 2*M_PI, 0);
    //設置圓的填充顏色
    [[UIColor grayColor]set];
   
    //3.渲染
//    CGContextStrokePath(ctx);
    CGContextFillPath(ctx);
}


@end

效果:

201512291701799.png (640×960)

201512291719993.png (640×960)

2.注意點:

drawRect:方法不能由我們自己手動調用,只能由系統來調用。
drawRect:調用的時機:當第一次顯示或者一個重繪事件發生時調用。
setNeedsDisplay方法:重新繪制,調用這個方法就會通知自定義的view重新繪制畫面,調用drawRect:。
提示:當一個view從xib或storyboard創建出來時,會調用awakefromnib方法。
3.補充

201512291739903.png (640×960)

201512291757725.png (640×960)

刷幀效果
說明:把雪花狀的圖片繪制到view上,實現圖片在視圖中下落的效果。
1.實現代碼:
復制代碼 代碼如下:
//
//  YYview.m
//  05-刷幀動畫
//
//  Created by apple on 14-6-11.
//  Copyright (c) 2014年 itcase. All rights reserved.
//

#import "YYview.h"

//私有擴展
@interface YYview  ()
@property(nonatomic,assign)float imageY;

@end
@implementation YYview


-(id)initWithCoder:(NSCoder *)aDecoder
{
    //請注意這裡一定要先初始化父類的構造方法
    if (self=[super initWithCoder:aDecoder]) {
        NSLog(@"initWithCoder:");
       
        //NSTimer一般用於定時的更新一些非界面上的數據,告訴多久調用一次
        //使用定時器,使用該定時器會出現卡頓的現象
//        [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(updateImage) userInfo:nil repeats:YES];
       
        // CADisplayLink刷幀,默認每秒刷新60次
        //該定時器創建之後,默認是不會執行的,需要把它加載到消息循環中
       CADisplayLink *display= [CADisplayLink displayLinkWithTarget:self selector:@selector(updateImage)];
        [display addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
    
    }
    return self;
}

-(void)updateImage
{
    //調用該方法重繪畫面
    [self setNeedsDisplay];
}
-(void)awakeFromNib
{
    NSLog(@"awakeFromNib");
}

- (void)drawRect:(CGRect)rect
{
    //把圖片繪制到view上

    //每次調用該方法對畫面進行重繪時,imageY的值就+5
    self.imageY+=5;
      //判斷,當雪花超出屏幕的時候,讓圖片從頭開始降落
    if (self.imageY>rect.size.height) {
        self.imageY=0;
    }
    UIImage *image=[UIImage imageNamed:@"snow"];
    [image drawAtPoint:CGPointMake(0, self.imageY)];

    UIImage *image2=[UIImage imageNamed:@"me"];
    [image2 drawAtPoint:CGPointMake(80, self.imageY)];
   
}

@end

實現效果

201512291816946.png (791×121)

2.重要說明

(1)下面兩個方法的調用順序

-(void)awakeFromNib

-(id)initWithCoder:(NSCoder *)aDecoder

提示:如果view是從xib或storyboard中創建可以調用awakefromnib方法,歸檔。從文件創建view,其實會先調用initwithcoder這個方法。xib和storyboard也是文件。

上面兩個方法,-(id)initWithCoder:(NSCoder *)aDecoder會先調用。實現該方法需要實現NSCoding協議,由於創建的UIView默認就已經實現了該協議。

可以進入到頭文件查看:

201512291816946.png (791×121)

運行新建的程序,通過打印可以驗證上面兩個方法的調用順序。

201512291906114.png (877×135)

(2)兩個定時器

第一個:
復制代碼 代碼如下:
[NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(updateImage) userInfo:nil repeats:YES];

說明: NSTimer一般用於定時的更新一些非界面上的數據,告訴多久調用一次

第二個:
復制代碼 代碼如下:
        CADisplayLink *display= [CADisplayLink displayLinkWithTarget:self selector:@selector(updateImage)];

        [display addToRunLoop:[NSRunLoopmainRunLoop] forMode:NSDefaultRunLoopMode];

  說明: CADisplayLink刷幀,默認每秒刷新60次。該定時器創建之後,默認是不會執行的,需要把它加載到消息循環中

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved