iOS开发中Quartz2D控制圆形缩放和实现刷帧效果

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或者显示器的窗口上)

相同的⼀套绘图序列,指定不同的Graphics Context,就可将相同的图像绘制到不同的目标上

四、自定义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

效果:

2.注意点:

drawRect:方法不能由我们自己手动调用,只能由系统来调用。
drawRect:调用的时机:当第一次显示或者一个重绘事件发生时调用。
setNeedsDisplay方法:重新绘制,调用这个方法就会通知自定义的view重新绘制画面,调用drawRect:。
提示:当一个view从xib或storyboard创建出来时,会调用awakefromnib方法。
3.补充

刷帧效果
说明:把雪花状的图片绘制到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

实现效果

2.重要说明

(1)下面两个方法的调用顺序

-(void)awakeFromNib

-(id)initWithCoder:(NSCoder *)aDecoder

提示:如果view是从xib或storyboard中创建可以调用awakefromnib方法,归档。从文件创建view,其实会先调用initwithcoder这个方法。xib和storyboard也是文件。

上面两个方法,-(id)initWithCoder:(NSCoder *)aDecoder会先调用。实现该方法需要实现NSCoding协议,由于创建的UIView默认就已经实现了该协议。

可以进入到头文件查看:

运行新建的程序,通过打印可以验证上面两个方法的调用顺序。

(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次。该定时器创建之后,默认是不会执行的,需要把它加载到消息循环中

(0)

相关推荐

  • iOS使用UIScorllView实现两指缩放功能

    两指缩放功能不仅可以用UIPinchGestureRecognizer手势来实现,还能用UIScorllView来实现,UIScrollView可以轻松的实现最大与最小缩放值,以及滚动的效果.代码如下: #import "ViewController.h" @interface ViewController () @property (weak, nonatomic) IBOutlet UIScrollView *scrollView; @property (strong, nonat

  • iOS应用开发中对UIImage进行截取和缩放的方法详解

    截取UIImage指定大小区域 最近遇到这样的需求:从服务器获取到一张照片,只需要显示他的左半部分,或者中间部分等等.也就是截取UIImage指定大小区域. UIImage扩展: 我的解决方案是对UIImage进行扩展.通过CGImageRef和CGImage完成截取,调用的方法是:CGImageCreateWithImageInRect.扩展类叫UIImage+Crop,具体代码如下: UIImage+Crop.h #import <UIKit/UIKit.h> typedef NS_ENU

  • iOS手势识别的详细使用方法(拖动,缩放,旋转,点击,手势依赖,自定义手势)

    手势识别在iOS上非常重要,手势操作移动设备的重要特征,极大的增加了移动设备使用便捷性. 1.UIGestureRecognizer介绍 手势识别在iOS上非常重要,手势操作移动设备的重要特征,极大的增加了移动设备使用便捷性. iOS系统在3.2以后,为方便开发这使用一些常用的手势,提供了UIGestureRecognizer类.手势识别UIGestureRecognizer类是个抽象类,下面的子类是具体的手势,开发这可以直接使用这些手势识别. UITapGestureRecognizer UI

  • iOS实现点击微信头像(放大、缩放、保存)效果

    先来看看实现效果(GIF): 实现思路: 直接自定义 UIView(CYPhotoPreviewer),为了实现双击缩放,可以实现 UIScrollViewDelegate 对应的方法.如果需要模糊背景,可以在自定义的 UIView 中先添加模糊背景,再添加 UIScrollView,继而在 UIScrollView 中添加图片容器,这个容器就是要显示的图片的 superView,代码一目了然: - (void)setup { self.frame = [UIScreenmainScreen].

  • iOS UITableView展开缩放动画实例代码

    Swift - UITableView展开缩放动画 效果 源码:https://github.com/YouXianMing/Swift-Animations // // HeaderViewTapAnimationController.swift // Swift-Animations // // Created by YouXianMing on 16/8/9. // Copyright © 2016年 YouXianMing. All rights reserved. // import

  • iOS应用开发中使用UIScrollView控件来实现图片缩放

    一.知识点简单介绍 1.UIScrollView控件是什么? (1)移动设备的屏幕⼤大⼩小是极其有限的,因此直接展⽰示在⽤用户眼前的内容也相当有限 (2)当展⽰示的内容较多,超出⼀一个屏幕时,⽤用户可通过滚动⼿手势来查看屏幕以外的内容 (3)普通的UIView不具备滚动功能,不能显⽰示过多的内容 (4)UIScrollView是一个能够滚动的视图控件,可以⽤用来展⽰示⼤大量的内容,并且可以通过滚 动查看所有的内容 (5)  举例:手机上的"设置".其他⽰示例程序 2.UIScrollV

  • iOS开发中Quartz2D控制圆形缩放和实现刷帧效果

    Quartz2D简要回顾 一.什么是Quartz2D Quartz 2D是⼀个二维绘图引擎,同时支持iOS和Mac系统 Quartz 2D能完成的工作: 绘制图形 : 线条\三角形\矩形\圆\弧等 绘制文字 绘制\生成图片(图像) 读取\生成PDF 截图\裁剪图片 自定义UI控件 二.Quartz2D在iOS开发中的价值 为了便于搭建美观的UI界面,iOS提供了UIKit框架,⾥⾯有各种各样的UI控件 UILabel:显⽰文字 UIImageView:显示图片 UIButton:同时显示图片和⽂

  • iOS开发中TableView类似QQ分组的折叠与展开效果

    类似QQ分组的样子,实现tableView的折叠与展开.其实要做这个效果我先想到的是在tableView中再嵌套多个tableView,这个想法实现起来就有点难了. 所以还是换个思路,把tableView的HeaderView用上了.给headerView加上手势,轻松解决折叠展开的问题. 直接上代码吧. @property (nonatomic, strong) UITableView *myTableView; @property (nonatomic, strong) NSMutableA

  • iOS开发中Quartz2D绘图路径的使用以及条纹效果的实现

    绘图路径 A.简单说明 在画线的时候,方法的内部默认创建一个path.它把路径都放到了path里面去. 1.创建路径  cgmutablepathref 调用该方法相当于创建了一个路径,这个路径用来保存绘图信息. 2.把绘图信息添加到路径里边. 以前的方法是点的位置添加到ctx(图形上下文信息)中,ctx 默认会在内部创建一个path用来保存绘图信息. 在图形上下文中有一块存储空间专门用来存储绘图信息,其实这块空间就是CGMutablePathRef. 3.把路径添加到上下文中. 代码示例: 绘

  • iOS开发中Quartz2D的基本使用方式举例

    一.画直线 代码: 复制代码 代码如下: // //  YYlineview.m //  03-画直线 // //  Created by apple on 14-6-9. //  Copyright (c) 2014年 itcase. All rights reserved. // #import "YYlineview.h" @implementation YYlineview // 当自定义view第一次显示出来的时候就会调用drawRect方法 - (void)drawRect

  • IOS开发中如何设计短信验证码防刷机制

    最近遇到一个关于防止短信验证码被刷的产品设计问题,后来在面试一个前来应聘JAVA开发的程序员的时候,他也提到了他以前公司的系统也遭遇过这个被刷短信的问题.因此,就"如何设计短信验证码防刷机制"作一个总结和分享. 1.时间限制:60秒后才能再次发送 从发送验证码开始,前端(客户端)会进行一个60秒的倒数,在这一分钟之内,用户是无法提交多次发送信息的请求的.这种方法虽然使用得比较普遍,但是却不是非常有用,技术稍微好点的人完全可以绕过这个限制,直接发送短信验证码. 2.手机号限制:同一个手机

  • iOS开发中AVPlayer的简单应用

    前言 在iOS开发中,播放视频通常有两种方式,一种是使用MPMoviePlayerController(需要导入MediaPlayer.Framework),还有一种是使用AVPlayer.关于这两个类的区别简而言之就是MPMoviePlayerController使用更简单,功能不如AVPlayer强大,而AVPlayer使用稍微麻烦点,不过功能更加强大.下面这篇文章主要介绍下AVPlayer的简单应用,需要的朋友们一起来看看吧. AVPlayer的简单应用 1.引入系统框架 2.创建视频的u

  • IOS 开发中画扇形图实例详解

    IOS 开发中画扇形图实例详解 昨天在做项目中,遇到一个需要显示扇形图的功能,网上搜了一下,发现code4app里面也没有找到我想要的那种类似的效果,没办法了,只能自己学习一下如何画了. 首先我们需要了解一个uiview的方法 -(void)drawRect:(CGRect)rect 我们知道了这个方法,就可以在自定义UIView的子类的- (void)drawRect:(CGRect)rect里面绘图了,关于drawrect的调用周期,网上也是一找一大堆,等下我会整理一下,转载一篇供你们参考.

  • iOS开发中使用UIScrollView实现无限循环的图片浏览器

    一.概述 UIKit框架中有大量的控件供开发者使用,在iOS开发中不仅可以直接使用这些控件还可以在这些控件的基础上进行扩展打造自己的控件.在这个系列中如果每个控件都介绍一遍确实没有必要,所谓授人以鱼不如授人以渔,这里会尽可能让大家明白其中的原理,找一些典型的控件进行说明,这样一来大家就可以触类旁通.今天我们主要来看一下UIScrollView的内容: UIView UIScrollView 实战--图片浏览器 二.UIView 在熟悉UIScrollView之前很有必要说一下UIView的内容.

  • IOS开发中的设计模式汇总

    iOS开发学习中,经常弄不清楚ios的开发模式,今天我们就来进行简单的总结和探讨~ (一)代理模式 应用场景:当一个类的某些功能需要由别的类来实现,但是又不确定具体会是哪个类实现. 优势:解耦合 敏捷原则:开放-封闭原则 实例:tableview的 数据源delegate,通过和protocol的配合,完成委托诉求. 列表row个数delegate 自定义的delegate (二)观察者模式 应用场景:一般为model层对,controller和view进行的通知方式,不关心谁去接收,只负责发布

  • IOS开发中加载大量网络图片优化方法

    IOS开发中加载大量网络图片如何优化 1.概述 在IOS下通过URL读一张网络图片并不像其他编程语言那样可以直接把图片路径放到图片路径的位置就ok,而是需要我们通过一段类似流的方式去加载网络图片,接着才能把图片放入图片路径显示.比如: -(UIImage *) getImageFromURL:(NSString *)fileURL { //NSLog(@"执行图片下载函数"); UIImage * result; NSData * data = [NSData dataWithCont

随机推荐