在iOS中Qutarz2D 详解及使用

(一)初识

介绍

Quartz 2D是二维绘图引擎。

能完成的工作有:

  1. 绘制图形 : 线条\三角形\矩\圆\弧
  2. 绘制文字
  3. 绘制\生成图片(图像)
  4. 读取\生PDF
  5. 截图\裁剪图片
  6. 自定义UI控件

在iOS中最主要的作用是:自定义View

废话不多说了,直接开始学习它吧。

概念开始

首先,必须清楚 图形上下文 的概念

  • 图形上下文(Graphics Context)是一个CGContentRef类型的数据;可以帮你把你要显示

    的图形显示到你指定的目标文件上。

  • 图形上下文的分类

    Quartz2D提供了以下几种类型的Graphics Contenxt类型:

    1.Bitmap Graphics Context

    2.PDF Graphics Context

    3.Windwo Graphics Context

    4.Layer Graphics Contenx

    5.Printer Graphics Context

    这几种样式的显示样式实例如下图所示:

现在我们直接来使用它吧

为了方便大家看懂我的代码,首先我们学习一下使用的具体步骤:

1.自定义一个View(自定义一个UI控件),用来在上面画图

2.在这个View类的DrawRect方法中画图:

  • 获取与该View相关的上下文

  • 设置图形的路径

  • 将路径添加到上下文(也就是显示出来)

实例展示一:

步骤:

1.自定义一个View

2.在自定义的View的DrawRect方法中画图

  1. //画一个三角形
  2. - (void)drawRect:(CGRect)rect {
  3. //获取当前上下文
  4. CGContextRef currentContext = UIGraphicsGetCurrentContext();
  5. /************************************************/
  6. //设置路径,开始点
  7. CGContextMoveToPoint(currentContext, 10, 10);
  8. //添加第二个点
  9. CGContextAddLineToPoint(currentContext, 100, 100);
  10. //添加第三个点
  11. CGContextAddLineToPoint(currentContext, 150, 40);
  12. //封闭区域
  13. CGContextClosePath(currentContext);
  14. /***********************************************/
  15. //将路径渲染到上下文并画出来
  16. CGContextStrokePath(currentContext);
  17. }

其他图形

把上面的/*****/注释的那一段换成其他的图形,就可以展示出其他的图形了。例如:

矩形
  1. /*画矩形*/
  2. CGContextStrokeRect(context,CGRectMake(100, 120, 10, 10));//画方框
  3. CGContextFillRect(context,CGRectMake(120, 120, 10, 10));//填充框
  4. //矩形,并填弃颜色
  5. CGContextSetLineWidth(context, 2.0);//线的宽度
  6. UIColor *aColor = [UIColor blueColor];//blue蓝色
  7. CGContextSetFillColorWithColor(context, aColor.CGColor);//填充颜色
  8. aColor = [UIColor yellowColor];
  9. CGContextSetStrokeColorWithColor(context, aColor.CGColor);//线框颜色
  10. CGContextAddRect(context,CGRectMake(140, 120, 60, 30));//画方框
  11. CGContextDrawPath(context, kCGPathFillStroke);//绘画路径
  12. //矩形,并填弃渐变颜色
  13. CAGradientLayer *gradient1 = [CAGradientLayer layer];
  14. gradient1.frame = CGRectMake(240, 120, 60, 30);
  15. gradient1.colors = [NSArray arrayWithObjects:
  16. (id)[UIColor whiteColor].CGColor,
  17. (id)[UIColor grayColor].CGColor,
  18. (id)[UIColor blackColor].CGColor,
  19. (id)[UIColor yellowColor].CGColor,
  20. (id)[UIColor blueColor].CGColor,
  21. (id)[UIColor redColor].CGColor,
  22. (id)[UIColor greenColor].CGColor,
  23. (id)[UIColor orangeColor].CGColor,
  24. (id)[UIColor brownColor].CGColor,
  25. nil];
  26. [self.layer insertSublayer:gradient1 atIndex:0];

文字
  1. //文字
  2. CGContextSetRGBFillColor(currentContext, 1, 0, 0, 1.0);
  3. UIFont *font = [UIFont boldSystemFontOfSize:15.0];
  4. [@"画汉字" drawInRect:CGRectMake(10, 10, 50, 100) withFont:font];

画圆
  1. //画圆
  2. //填充模式:
  3. //kCGPathFill填充非零绕数规则,
  4. //kCGPathEOFill表示用奇偶规则,
  5. //kCGPathStroke路径,
  6. //kCGPathFillStroke路径填充,
  7. //kCGPathEOFillStroke表示描线,不是填充
  8. //画圆函数
  9. //void CGContextAddArc(CGContextRef c,CGFloat x, CGFloat y,CGFloat radius,CGFloat startAngle,CGFloat endAngle, int clockwise)
  10. // x,y为圆点坐标,radius半径,startAngle为开始的弧度,endAngle为 结束的弧度,clockwise 0为顺时针,1为逆时针。
  11. //设置
  12. CGContextSetRGBStrokeColor(context,1,1,1,1.0);//画笔线的颜色
  13. CGContextSetLineWidth(context, 2.0);//线的宽度
  14. //边框圆
  15. CGContextAddArc(context, 100, 20, 15, 0, 2*M_PI, 0); //添加一个圆
  16. CGContextDrawPath(context, kCGPathStroke); //绘制路径
  17. //填充圆,无边框
  18. CGContextAddArc(context, 150, 30, 30, 0, 2*M_PI, 0); //添加一个圆
  19. CGContextDrawPath(context, kCGPathFill);//绘制填充
  20. //画大圆并填充颜色
  21. UIColor*aColor = [UIColor colorWithRed:1 green:0.0 blue:0 alpha:1];
  22. CGContextSetFillColorWithColor(context, aColor.CGColor);//填充颜色
  23. CGContextSetLineWidth(context, 3.0);//线的宽度
  24. CGContextAddArc(context, 250, 40, 40, 0, 2*M_PI, 0); //添加一个圆
  25. CGContextDrawPath(context, kCGPathFillStroke); //绘制路径加填充

圆弧
  1. //圆弧
  2. CGContextSetRGBStrokeColor(context, 0, 0, 1, 1);//改变画笔颜色
  3. CGContextMoveToPoint(context, 140, 80);//开始坐标p1
  4. //CGContextAddArcToPoint(CGContextRef c, CGFloat x1, CGFloat y1,CGFloat x2, CGFloat y2, CGFloat radius)
  5. //x1,y1跟p1形成一条线,x2,y2跟x1,y1坐标形成一条线,然后将这两条线作为切线,画出圆心求出半径,radius半径,注意, 需要算好半径的长度,
  6. CGContextAddArcToPoint(context, 148, 68, 156, 80, 10);
  7. CGContextStrokePath(context);//绘画路径

椭圆、圆角按钮、图片、贝塞尔曲线

  1. //画椭圆
  2. CGContextAddEllipseInRect(context, CGRectMake(160, 180, 20, 8)); //椭圆
  3. CGContextDrawPath(context, kCGPathFillStroke);
  4. /*画圆角矩形*/
  5. float fw = 180;
  6. float fh = 280;
  7. CGContextMoveToPoint(context, fw, fh-20); // 开始坐标右边开始
  8. CGContextAddArcToPoint(context, fw, fh, fw-20, fh, 10); // 右下角角度
  9. CGContextAddArcToPoint(context, 120, fh, 120, fh-20, 10); // 左下角角度
  10. CGContextAddArcToPoint(context, 120, 250, fw-20, 250, 10); // 左上角
  11. CGContextAddArcToPoint(context, fw, 250, fw, fh-20, 10); // 右上角
  12. CGContextClosePath(context);
  13. CGContextDrawPath(context, kCGPathFillStroke); //根据坐标绘制路径
  14. /*画贝塞尔曲线*/
  15. //二次曲线
  16. CGContextMoveToPoint(context, 120, 300);//设置Path的起点
  17. CGContextAddQuadCurveToPoint(context,190, 310, 120, 390);//设置贝塞尔曲线的控制点坐标和终点坐标
  18. CGContextStrokePath(context);
  19. //三次曲线函数
  20. CGContextMoveToPoint(context, 200, 300);//设置Path的起点
  21. CGContextAddCurveToPoint(context,250, 280, 250, 400, 280, 300);//设置贝塞尔曲线的控制点坐标和控制点坐标终点坐标
  22. CGContextStrokePath(context);
  23. /*图片*/
  24. UIImage *image = [UIImage imageNamed:@"Snip20150715_1"];
  25. [image drawInRect:CGRectMake(60, 340, 60, 60)];//在坐标中画出图片
  26. // [image drawAtPoint:CGPointMake(100, 340)];//保持图片大小在point点开始画图片
  27. CGContextDrawImage(context, CGRectMake(100, 340, 60, 60), image.CGImage);//使图片上下颠倒

这里就不贴图了。

下面综合案例,画出自己的表情小黄人

实现效果:

代码如下:


  1. //
  2. // YLView.m
  3. // 我的QQ表情
  4. // 联系方式: 492199045@qq.com
  5. // Created by 薛银亮 on 15/7/15.
  6. // Copyright (c) 2015年 薛银亮. All rights reserved.
  7. //
  8. #import "YLView.h"
  9. #define YLColor(r, g, b) [UIColor colorWithRed:r / 255.0 green:g / 255.0 blue:b / 255.0 alpha:1.1]
  10. @implementation YLView
  11. - (void)drawRect:(CGRect)rect {
  12. //获取当前上下文
  13. CGContextRef context = UIGraphicsGetCurrentContext();
  14. //画身体
  15. //头圆
  16. CGFloat x = self.bounds.size.width * 0.5;
  17. CGFloat y = self.bounds.size.height /3;
  18. CGFloat radius = self.bounds.size.width / 4;
  19. CGContextAddArc(context, x, y, radius, 0, M_PI, 1);
  20. //身线
  21. CGFloat h = y + 150;
  22. CGContextAddLineToPoint(context, x-radius, h);
  23. //下巴
  24. CGContextAddArc(context, x, h, radius, M_PI, 2*M_PI, 1);
  25. CGContextClosePath(context);
  26. //颜色
  27. [YLColor(249, 201, 40) setFill];
  28. CGContextFillPath(context);
  29. //画嘴
  30. CGFloat zuiqX = x-radius/4 -10;
  31. CGFloat zuiqY = h-20;
  32. CGFloat kongX = x;
  33. CGFloat kongY = zuiqY + 15;
  34. CGFloat zhongX = x + radius / 4 +10;
  35. CGFloat zhongY = zuiqY;
  36. CGContextMoveToPoint(context, zuiqX, zuiqY);
  37. CGContextAddQuadCurveToPoint(context, kongX, kongY, zhongX, zhongY);
  38. [YLColor(0 , 0, 0) setStroke];
  39. CGContextSetLineWidth(context, 4);
  40. CGContextStrokePath(context);
  41. //画牙
  42. CGContextMoveToPoint(context, x-5, kongY-5);
  43. CGFloat yazhongX = x -5;
  44. CGFloat yazhongY = kongY +10;
  45. [YLColor(255, 255, 255) set];
  46. CGContextAddLineToPoint(context, yazhongX, yazhongY);
  47. CGContextSetLineWidth(context, 12);
  48. // CGContextSetLineCap(context, kCGLineCapRound);
  49. CGContextStrokePath(context);
  50. //画头符
  51. CGRect toufuRect = CGRectMake(x - radius, y, 2*radius, 30);
  52. CGContextAddRect(context, toufuRect);
  53. [YLColor(0, 0, 0) setFill];
  54. CGContextFillPath(context);
  55. //画头符汉字
  56. NSString *toufuString = @"iOS黄人";
  57. CGRect toufuStrRect = CGRectMake(zuiqX, y+4, radius, 30);
  58. NSMutableDictionary *toufuStrDict = [NSMutableDictionary dictionary];
  59. toufuStrDict[NSFontAttributeName] = [UIFont systemFontOfSize:20 weight:6];
  60. toufuStrDict[NSForegroundColorAttributeName] = [UIColor redColor];
  61. [toufuString drawInRect:toufuStrRect withAttributes:toufuStrDict];
  62. CGContextStrokePath(context);
  63. //画眼睛
  64. //左眼
  65. CGContextMoveToPoint(context, zuiqX, y+50);
  66. CGFloat zyanzhongX = zuiqX;
  67. CGFloat zyanzhongY = y + 60;
  68. [YLColor(0, 0, 0) set];
  69. CGContextAddLineToPoint(context, zyanzhongX, zyanzhongY);
  70. CGContextSetLineWidth(context, 8);
  71. CGContextSetLineCap(context, kCGLineCapRound);
  72. //右眼
  73. CGContextMoveToPoint(context, zhongX, y+50);
  74. CGFloat yyanzhongX = zhongX;
  75. CGFloat yyanzhongY = y + 60;
  76. CGContextAddLineToPoint(context, yyanzhongX, yyanzhongY);
  77. CGContextStrokePath(context);
  78. }
  79. @end

(二)进阶

上下文栈

上面的案例可以看出来存在很多不恰当的地方,我们每次画出来一部分都要重新设置当前上下文的状态,以便下一次的使用。

这在使用的过程中很不方便,所以就有了图形上下文栈的操作。

假如我们知道当前上下文的状态在以后会使用,但是紧接着我们要使用其他的上下文状态,这时候,我们就可以把当前的上下文保存起来,相当于拷贝的操作,并存储在栈顶中:

保存:

  1. void CGContextSaveGState(CGContextRef c)

当我们需要重新使用这个状态的上下文的时候,就可以将上下文出栈,替换掉当前正在使用的上下文。


  1. void CGContextRestoreGState(CGContextRef c)

举例:

我们先画出来一个圆形和一个正方形,然后再来看看问题所在

  1. - (void)drawRect:(CGRect)rect {
  2. //获得当前上下文
  3. CGContextRef context = UIGraphicsGetCurrentContext();
  4. //设置所画的图形的颜色和线宽
  5. CGContextSetLineWidth(context, 10);
  6. [[UIColor redColor]setStroke];
  7. //画一个圆形
  8. CGContextAddEllipseInRect(context, CGRectMake(100, 100, 50, 50));
  9. //显示出来所画的图形
  10. CGContextStrokePath(context);
  11. //画一个正方形
  12. CGContextAddRect(context, CGRectMake(200, 200, 50, 50));
  13. //显示出来所画的图形
  14. CGContextStrokePath(context);
  15. }

如果我们想给正方形设置成黑色的细线形状,那么,我们就要重新设置LineWight和Color。这看起来是没有问题的。但是如果我们画的不只是两个不一样的图形,而是多个,那么这样就显得非常的麻烦。下面我们看看怎么使用上下文栈解决这个问题:

  1. - (void)drawRect:(CGRect)rect {
  2. //获得当前上下文
  3. CGContextRef context = UIGraphicsGetCurrentContext();
  4. //保存上下文的初始状态,以便后面使用
  5. CGContextSaveGState(context);
  6. //设置所画的图形的颜色和线宽
  7. CGContextSetLineWidth(context, 10);
  8. [[UIColor redColor]setStroke];
  9. //画一个圆形
  10. CGContextAddEllipseInRect(context, CGRectMake(100, 100, 50, 50));
  11. CGContextStrokePath(context);
  12. //拿出上次保存的上下文的状态,用来设置正方形那个的样子
  13. CGContextRestoreGState(context);
  14. //画一个正方形
  15. CGContextAddRect(context, CGRectMake(200, 200, 50, 50));
  16. //显示出来所画的图形
  17. CGContextStrokePath(context);
  18. }

矩阵操作

所谓的矩阵操作就是将类似于我们之前的所有的画线操作一起进行一些操作,比如:旋转、平移、缩放等。

下面,我们将上面的知识点举个例子学习一下:

我们将上面的例子中的圆形和正方形同时进行旋转、平移等操作:

  1. - (void)drawRect:(CGRect)rect {
  2. //获得当前上下文
  3. CGContextRef context = UIGraphicsGetCurrentContext();
  4. //矩阵操作
  5. //旋转
  6. CGContextRotateCTM(context, M_1_PI);
  7. //平移
  8. CGContextTranslateCTM(context, 0, 100);
  9. //缩放
  10. CGContextScaleCTM(context, 1.5, 0.5);
  11. //保存上下文的初始状态,以便后面使用
  12. CGContextSaveGState(context);
  13. //设置所画的图形的颜色和线宽
  14. CGContextSetLineWidth(context, 10);
  15. [[UIColor redColor]setStroke];
  16. //画一个圆形
  17. CGContextAddEllipseInRect(context, CGRectMake(100, 100, 50, 50));
  18. CGContextStrokePath(context);
  19. //拿出上次保存的上下文的状态,用来设置正方形那个的样子
  20. CGContextRestoreGState(context);
  21. //画一个正方形
  22. CGContextAddRect(context, CGRectMake(200, 200, 50, 50));
  23. //显示出来所画的图形
  24. CGContextStrokePath(context);
  25. }

裁剪

剪裁一

显示在指定的UIView上

我们可以把一张图片裁剪成自己想要的图形

  • 设置好要裁剪的图形
  • 将准备好的图片放在裁剪区域

示例:


  1. - (void)drawRect:(CGRect)rect {
  2. //获得当前上下文
  3. CGContextRef context = UIGraphicsGetCurrentContext();
  4. //截图操作
  5. //画出要截取的区域-圆
  6. CGContextAddEllipseInRect(context, CGRectMake(100, 100, 100, 100));
  7. //剪裁
  8. CGContextClip(context);
  9. CGContextFillPath(context);
  10. //添加一张图片
  11. UIImage *image = [UIImage imageNamed:@"Snip20150716_10"];
  12. [image drawInRect:CGRectMake(50, 50, 200, 200)];
  13. }

剪裁二

显示成一张图片,方便使用。

显示结果:

我们可以把这个功能抽取成UIImage的分类,以便以后的使用:


  1. + (instancetype)circleImageWithName:(NSString *)name borderWidth:(CGFloat)borderWidth borderColor:(UIColor *)borderColor
  2. {
  3. // 1.加载原图
  4. UIImage *oldImage = [UIImage imageNamed:name];
  5. // 2.开启上下文
  6. CGFloat imageW = oldImage.size.width + 2 * borderWidth;
  7. CGFloat imageH = oldImage.size.height + 2 * borderWidth;
  8. CGSize imageSize = CGSizeMake(imageW, imageH);
  9. UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0.0);
  10. // 3.取得当前的上下文
  11. CGContextRef ctx = UIGraphicsGetCurrentContext();
  12. // 4.画边框(大圆)
  13. [borderColor set];
  14. CGFloat bigRadius = imageW * 0.5; // 大圆半径
  15. CGFloat centerX = bigRadius; // 圆心
  16. CGFloat centerY = bigRadius;
  17. CGContextAddArc(ctx, centerX, centerY, bigRadius, 0, M_PI * 2, 0);
  18. CGContextFillPath(ctx); // 画圆
  19. // 5.小圆
  20. CGFloat smallRadius = bigRadius - borderWidth;
  21. CGContextAddArc(ctx, centerX, centerY, smallRadius, 0, M_PI * 2, 0);
  22. // 裁剪(后面画的东西才会受裁剪的影响)
  23. CGContextClip(ctx);
  24. // 6.画图
  25. [oldImage drawInRect:CGRectMake(borderWidth, borderWidth, oldImage.size.width, oldImage.size.height)];
  26. // 7.取图
  27. UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
  28. // 8.结束上下文
  29. UIGraphicsEndImageContext();
  30. return newImage;
  31. }

补充:我们一般会将画好的图像保存起来。保存到沙河Documents的方法如下:

  1. //先将图片压缩
  2. NSData *data = UIImagePNGRepresentation(newImage);
  3. NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"new.png"];
  4. [data writeToFile:path atomically:YES];

重绘(刷帧)

在使用绘画的时候,我们经常要不断的更新画面,但是系统的

  1. - (void)drawRect:(CGRect)rect;

这个函数只会默认调用一次,而且我们不能手动去调用(因为我们在其他地方无法获取到系统的上下文)。所以就要用到重绘了。

所谓重绘,关键要用到这个函数:

  1. - (void)setNeedsDisplay;

在重绘的时候,我们有时候会用到定时器,这里补充一下定时器知识,我们可以使用这两种定时器,例子:

  1. CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(setNeedsDisplay)];
  2. [link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];

这种定时器会默认在1秒钟刷新60次,而且使用时候要加入到主运行循环中,这样有时候会看着更加的流畅。

第二种:

  1. [NSTimer scheduledTimerWithTimeInterval:0.2 target:self selector:@selector(setNeedsDisplay) userInfo:nil repeats:YES];

这种用户可以自定义刷新的频率

例子:

贴出一个雪花下降的程序:


  1. #import "YLView.h"
  2. @interface YLView()
  3. /**y值*/
  4. @property(nonatomic,assign) CGFloat snowY;
  5. @end
  6. @implementation YLView
  7. -(void)awakeFromNib
  8. {
  9. CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(setNeedsDisplay)];
  10. [link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
  11. // [NSTimer scheduledTimerWithTimeInterval:0.2 target:self selector:@selector(setNeedsDisplay) userInfo:nil repeats:YES];
  12. }
  13. - (void)drawRect:(CGRect)rect {
  14. self.snowY +=5;
  15. UIImage *image = [UIImage imageNamed:@"snow.jpg"];
  16. [image drawAtPoint:CGPointMake(0, self.snowY)];
  17. }

制作水印图片

水印图片是指在一张图片上面添加上属于自己的标志,例如很多商标图片上面的右下角都会有一个小小的标志。下面我们画一个这样的例子。

效果如下

像这样的例子,可能会经常用到,所以我们最好将这个功能封装成一个分类。这里因为是UIImage的功能,所以我们将其封装成UIImage的分类。

代码示例:


  1. //
  2. // UIImage+Water.m
  3. // 打水印
  4. // 联系方式: 492199045@qq.com
  5. // Created by 薛银亮 on 15/7/17.
  6. // Copyright (c) 2015年 薛银亮. All rights reserved.
  7. // 水印图片
  8. #import "UIImage+Water.h"
  9. @implementation UIImage (Water)
  10. +(UIImage *)imageWithWaterBackGroundImage:(NSString *)backgroundImageString IconImageString:(NSString *)iconImageString
  11. {
  12. //背景图片
  13. UIImage *backImage = [UIImage imageNamed:backgroundImageString];
  14. //水印图标
  15. UIImage *iconImage = [UIImage imageNamed:iconImageString];
  16. //开启一个图片上下文
  17. UIGraphicsBeginImageContextWithOptions(backImage.size, NO, 0.0);
  18. //画背景
  19. CGFloat backW = backImage.size.width;
  20. CGFloat backH = backImage.size.height;
  21. [backImage drawInRect:CGRectMake(0, 0, backW, backH)];
  22. //画水印
  23. //计算水印所在的位置
  24. CGFloat margin = 10;
  25. CGFloat scale = 0.1;
  26. CGFloat iconW = iconImage.size.width * scale;
  27. CGFloat iconH = iconImage.size.height * scale;
  28. CGFloat X = backW - iconW - margin;
  29. CGFloat Y = backH - iconH - margin;
  30. [iconImage drawInRect:CGRectMake(X, Y, iconW, iconH)];
  31. //获取图形上下文的图片
  32. UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
  33. //结束图形上下文
  34. UIGraphicsEndImageContext();
  35. return newImage;
  36. }
  37. @end

屏幕截屏

这里也封装到UIImage的分类中了


  1. + (instancetype)captureWithView:(UIView *)view
  2. {
  3. // 1.开启上下文
  4. UIGraphicsBeginImageContextWithOptions(view.frame.size, NO, 0.0);
  5. // 2.将控制器view的layer渲染到上下文
  6. [view.layer renderInContext:UIGraphicsGetCurrentContext()];
  7. // 3.取出图片
  8. UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
  9. // 4.结束上下文
  10. UIGraphicsEndImageContext();
  11. return newImage;
  12. }

iOS中-Qutarz2D详解及使用的更多相关文章

  1. iOS中NSUserDefaults详解

    NSUserDefault 作为iOS中一种轻量级数据本地化方式,简单易用,经常用于存储一些应用相关属性记录,例如图书app的背景色,进度,上次阅读的书籍及相关配置信息.NSUserDefault实质 ...

  2. 转载]IOS LBS功能详解[0](获取经纬度)[1](获取当前地理位置文本 )

    原文地址:IOS LBS功能详解[0](获取经纬度)[1](获取当前地理位置文本作者:佐佐木小次郎 因为最近项目上要用有关LBS的功能.于是我便做一下预研. 一般说来LBS功能一般分为两块:一块是地理 ...

  3. iOS 2D绘图详解(Quartz 2D)之路径(点,直线,虚线,曲线,圆弧,椭圆,矩形)

    前言:一个路径可以包含由一个或者多个shape以及子路径subpath,quartz提供了很多方便的shape可以直接调用.例如:point,line,Arc(圆弧),Curves(曲线),Ellip ...

  4. iOS开发:详解Objective-C runTime

    Objective-C总Runtime的那点事儿(一)消息机制 最近在找工作,Objective-C中的Runtime是经常被问到的一个问题,几乎是面试大公司必问的一个问题.当然还有一些其他问题也几乎 ...

  5. iOS应用开发详解

    <iOS应用开发详解> 基本信息 作者: 郭宏志    出版社:电子工业出版社 ISBN:9787121207075 上架时间:2013-6-28 出版日期:2013 年7月 开本:16开 ...

  6. 了解iOS消息推送一文就够:史上最全iOS Push技术详解

    本文作者:陈裕发, 腾讯系统测试工程师,由腾讯WeTest整理发表. 1.引言 开发iOS系统中的Push推送,通常有以下3种情况: 1)在线Push:比如QQ.微信等IM界面处于前台时,聊天消息和指 ...

  7. iOS开发者证书-详解

    iOS开发者证书-详解/生成/使用 本文假设你已经有一些基本的Xcode开发经验, 并注册了iOS开发者账号. 相关基础 加密算法 现代密码学中, 主要有两种加密算法: 对称密钥加密 和 公开密钥加密 ...

  8. iOS开发-Runtime详解

    iOS开发-Runtime详解 简介 Runtime 又叫运行时,是一套底层的 C 语言 API,其为 iOS 内部的核心之一,我们平时编写的 OC 代码,底层都是基于它来实现的.比如: [recei ...

  9. winxp计算机管理中服务详解

    winxp计算机管理中服务详解01 http://blog.sina.com.cn/s/blog_60f923b50100efy9.html http://blog.sina.com.cn/s/blo ...

随机推荐

  1. Android自己主动化測试解决方式

    如今,已经有大量的Android自己主动化測试架构或工具可供我们使用,当中包含:Activity Instrumentation, MonkeyRunner, Robotium, 以及Robolect ...

  2. 分布式缓存技术redis学习(四)——redis高级应用(集群搭建、集群分区原理、集群操作)

    本文是redis学习系列的第四篇,前面我们学习了redis的数据结构和一些高级特性,点击下面链接可回看 <详细讲解redis数据结构(内存模型)以及常用命令> <redis高级应用( ...

  3. java 访问修饰符

    此题考察修饰符,函数定义等,故从网上搜罗了下相关资料,总结如下: 类.方法.成员变量和局部变量的可用修饰符 修饰符 类 成员访求 构造方法 成员变量 局部变量 abstract(抽象的) √ √ - ...

  4. JAVA基础之正则表达式

    加 ^$  整个字符串满足要求 不加部分字符串满足要求即可通过 ======================================================== \:转义字符 \d:任 ...

  5. 转 如何使用velocity模板引擎开发网站

    基于 Java 的网站开发,很多人都采用 JSP 作为前端网页制作的技术,尤其在是国内.这种技术通常有一些问题,我试想一下我们是怎样开发网站的,通常有几种方法: 1:功能确定后,由美工设计网页的UI( ...

  6. [Java] SSH框架笔记_框架分析+环境搭建+实例源码下载

    首先,SSH不是一个框架,而是多个框架(struts+spring+hibernate)的集成,是目前较流行的一种Web应用程序开源集成框架,用于构建灵活.易于扩展的多层Web应用程序. 集成SSH框 ...

  7. 【Android 界面效果36】Fragment管理

    要管理fragment们,需使用FragmentManager,要获取它,需在activity中调用方法getFragmentManager(). 你可以用FragmentManager来做以上事情: ...

  8. 函数参数选项的处理getopt getopt_long getopt_long_only

    转载:http://blog.chinaunix.net/uid-20321537-id-1966849.html   在头文件中int getopt(int argc,char *argv[], c ...

  9. IceFig阅读笔记

    嗯:就是这里了 http://research.worksap.com/research/icefig/ 一下阅读笔记: 嗯,时间有限,他们提供的又茫茫多,所以 就找出来了 几个 单独聊聊吧. 其他语 ...

  10. UML类图中的六大关系:泛化、实现、依赖、关联、聚合、组合关系

    UML定义的关系主要有:泛化.实现.依赖.关联.聚合.组合,这六种关系紧密程度依次加强,分别看一下 1.泛化 概念:泛化是一种一般与特殊.一般与具体之间关系的描述,具体描述建立在一般描述的基础之上,并 ...