20.0~20.17 图像与动画

20.0. IntroductionGraphics and Animations

你应该看过很多界面很漂亮的应用,他们给你留下了很深的印象。iOS runtime 和 Cocoa 使你能够以相对简单的代码实现漂亮的界面和动画。当然了,漂亮的界面和动画是程序员和美工共同劳动的结果。在本章中,你将看到借助一些简单的编程技巧,你能实现什么。

Cocoa应用中,应用是由windows和views组成。一个应用至少有一个window,但可以有很多个view。window是UIWindow类。通常应用就是在window上放置很多的view。如buttons,labels,images 等。这些控件由UIKit来绘画。

会不会很难理解呢,不过通过本章,相信你将会慢慢了解他们。

苹果已经提供了一些强悍的框架来绘图,稍微看下:

UIKit: 创建view, window,button和其他UI相关控件,包括由某些低级api合成的高级api。

Quartz 2D: iOS绘画主引擎;UIKit使用的是Quartz

Core Graphics:支持图像导入,绘制等得框架

Core Animation:iOS 动画实现

画图中最重要的一个概念是point 和 pixel的区别。可能大家已经很熟悉pixel,那什么是point呢?They’re the device-independent counterpart of pixels。当写代码时设置的宽高,iOS把它当做point对待,而不是pixel

。比如你想填充,iPhone 5的整个屏幕,你设置其宽度为320,高度为568。但是其屏幕的实际分辨率是640*1136。这就是point的厉害之处,它处理了缩放因子(content scale factor

缩放因子是一个浮点值,是一个逻辑的point到实际的pixel的一个转换值,iPhone 5的缩放因子是2.0

-------------我的理解,这里的point其实相当于Android 中得dp,dip--------------------

本章中,我们将使用view来画图形,字符串等

为了运行本章的代码,需要你子类化UIView,并把控制器的view的类名改成新建的View


20.1. Enumerating and Loading Fonts

枚举内置字体

- (void) enumerateFonts{

    for (NSString *familyName in [UIFont familyNames]){

        NSLog(@"Font Family = %@", familyName);

        for (NSString *fontName in [UIFont fontNamesForFamilyName:familyName]){

            NSLog(@"\tfontName=%@", fontName);

        }

    }

}


打印:

2014-07-30 15:47:25.088 cookbook7_20[485:a0b] Font Family = Thonburi

2014-07-30 15:47:25.089 cookbook7_20[485:a0b] fontName=Thonburi-Bold

2014-07-30 15:47:25.089 cookbook7_20[485:a0b] fontName=Thonburi

2014-07-30 15:47:25.090 cookbook7_20[485:a0b] fontName=Thonburi-Light

2014-07-30 15:47:25.090 cookbook7_20[485:a0b] Font Family = Snell Roundhand

2014-07-30 15:47:25.091 cookbook7_20[485:a0b] fontName=SnellRoundhand-Black

2014-07-30 15:47:25.091 cookbook7_20[485:a0b] fontName=SnellRoundhand-Bold

2014-07-30 15:47:25.092 cookbook7_20[485:a0b] fontName=SnellRoundhand

2014-07-30 15:47:25.092 cookbook7_20[485:a0b] Font Family = Academy Engraved LET

2014-07-30 15:47:25.093 cookbook7_20[485:a0b] fontName=AcademyEngravedLetPlain

2014-07-30 15:47:25.093 cookbook7_20[485:a0b] Font Family = Marker Felt

2014-07-30 15:47:25.093 cookbook7_20[485:a0b] fontName=MarkerFelt-Thin

2014-07-30 15:47:25.094 cookbook7_20[485:a0b] fontName=MarkerFelt-Wide

2014-07-30 15:47:25.094 cookbook7_20[485:a0b] Font Family = Avenir

。。。。。。



字体被分成了家族,也就有了家族名称和各个字体的名称。

知道了字体名称,就可以导入字体了




-(void)testLoadfont

{

    __unused UIFont *font = [UIFont fontWithName:@"Thonburi-Bold"

                                            size:12.0f];

    NSLog(@"font=%@",font);

}

打印:

2014-07-30 15:53:18.478 cookbook7_20[506:a0b] font=<UICTFont: 0x89652a0> font-family: "Thonburi"; font-weight: bold; font-style: normal; font-size: 12.00pt


当然了,也可以用systemFontOfSize:  boldSystemFontOfSize:等来导入字体,系统默认字体是Helvetica.



20.2. Drawing Text


画字符串

使用NSString的drawAtPoint:withFont:




#import "View.h"


@implementation View


- (id)initWithFrame:(CGRect)frame

{

    self = [super initWithFrame:frame];

    if (self) {

        // Initialization code

    }

    return self;

}



// Only override drawRect: if you perform custom drawing.

// An empty implementation adversely affects performance during animation.

- (void)drawRect:(CGRect)rect

{

    UIFont *helveticaBold = [UIFont fontWithName:@"HelveticaNeue-Bold"

                                            size:40.0f];

    NSString *myString = @"Some String";

    //NS_AVAILABLE_IOS(7_0);

    [myString drawAtPoint:CGPointMake(40, 180)

           withAttributes:@{

                            NSFontAttributeName : helveticaBold

                            }];

}



@end


运行结果



20.3. Constructing, Setting, and Using Colors

创建设置使用颜色

-(void)drawRect:(CGRect)rect

{

    /* Load the color */

    UIColor *magentaColor =[UIColor colorWithRed:0.5f

                                           green:0.0f

                                            blue:0.5f

                                           alpha:1.0f];

    /* Set the color in the graphical context */

    [magentaColor set];

    /* Load the font */

    UIFont *helveticaBold = [UIFont fontWithName:@"HelveticaNeue-Bold"

                                            size:30.0f];

    /* Our string to be drawn */

    NSString *myString = @"I Learn Really Fast";

    /* Draw the string using the font. The color has

     already been set */

    [myString drawAtPoint:CGPointMake(25, 190)

           withAttributes:@{

                            NSFontAttributeName : helveticaBold

                            }];

    

}

运行:




使用drawWithRect:options:attributes:context:来限制显示区域


-(void)drawRect:(CGRect)rect

{

    /* Load the color */

    UIColor *magentaColor = [UIColor colorWithRed:0.5f

                                            green:0.0f

                                             blue:0.5f

                                            alpha:1.0f];

    /* Set the color in the graphical context */

    [magentaColor set];

    /* Load the font */

    UIFont *helveticaBold = [UIFont boldSystemFontOfSize:30];

    /* Our string to be drawn */

    NSString *myString = @"I Learn Really Fast";

    /* Draw the string using the font. The color has

     already been set */

    [myString drawWithRect:CGRectMake(100, /* x */

                                      120, /* y */

                                      100, /* width */

                                      200)

                   options:NSStringDrawingUsesLineFragmentOrigin

                attributes:@{

                             NSFontAttributeName : helveticaBold

                             }

                   context:nil];

    

}


运行:



UIColor是对CGColor的封装,深入core Graphics的底层,将获得更多的操控。

如何获取颜色的各个色值


-(void)drawRect:(CGRect)rect

{

    /* Load the color */

    UIColor *steelBlueColor = [UIColor colorWithRed:0.3f

                                              green:0.4f

                                               blue:0.6f

                                              alpha:1.0f];

    CGColorRef colorRef = steelBlueColor.CGColor;

    const CGFloat *components = CGColorGetComponents(colorRef);

    NSUInteger componentsCount = CGColorGetNumberOfComponents(colorRef);

    NSUInteger counter = 0; for (counter = 0;

                                 counter < componentsCount;

                                 counter++){

        NSLog(@"Component %lu = %.02f",

              (unsigned long)counter + 1, components[counter]);

    }

}

运行:

2014-07-30 17:18:11.609 cookbook7_20[809:a0b] Component 1 = 0.30

2014-07-30 17:18:11.609 cookbook7_20[809:a0b] Component 2 = 0.40

2014-07-30 17:18:11.610 cookbook7_20[809:a0b] Component 3 = 0.60

2014-07-30 17:18:11.610 cookbook7_20[809:a0b] Component 4 = 1.00


20.4. Drawing Images

画图

1,打开xcode的目录,找到xcode.icns文件,复制出来

2,打开xcode.icns文件,右键导出页面1,png保存

3,工程中引用xcode.png文件


-(void)drawRect:(CGRect)rect

{

    UIImage *image = [UIImage imageNamed:@"Xcode"];

    if (image != nil){

        NSLog(@"Successfully loaded the image.");

    } else {

        NSLog(@"Failed to load the image.");

    }

    

    /* Assuming the image is in your app bundle and we can load it */

    UIImage *xcodeIcon = [UIImage imageNamed:@"Xcode"];

    [xcodeIcon drawAtPoint:CGPointMake(0.0f,

                                       20.0f)];

    [xcodeIcon drawInRect:CGRectMake(50.0f,

                                     10.0f,

                                     40.0f,

                                     35.0f)];

}


运行:

2014-07-30 17:34:14.143 cookbook7_20[886:a0b] Successfully loaded the image.




20.5. Constructing Resizable Images

创建可变大小的图片 resizableImageWithCapInsets

当图片的大小与显示控件的大小不一致,又想让图片充满整个控件,该怎么办呢?可以用平铺的方式,也可以用拉伸的方式,本节介绍平铺的方式。

可能一般的平铺和拉伸你都懂的。但本章介绍的这种你可能不懂。他可以指定对图片中的某块区域进行平铺和拉伸,而不是对整张图片

这样做的好处是,你可以在保持图片的4个角不变形。

nine-part images



分成九部分图之后,就可以以一种更好的方式来调整图片的大小。

当需要resize图片大小的时候4个角是的部分是不变的。其他部分如下:

Top edgeBottom edge:只变宽度,不变高度

Left edgeRight edge:只变高度,不变宽度

Center:宽度,高度都会改变

通过UIEdgeInsets可以吧一张图分成9部分

typedef struct UIEdgeInsets {
CGFloat top, left, bottom, right;

} UIEdgeInsets;


#import "ViewController.h"


@interface ViewController ()

@property (strong, nonatomic) UIButton *button;


@end


@implementation ViewController


- (void)viewDidLoad

{

    [super viewDidLoad];

// Do any additional setup after loading the view, typically from a nib.

    [self testresizableImageWithCapInsets];

}


- (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}


-(UIButton *)getButton

{

    UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom];

    [button setFrame:CGRectMake(0.0f, 0.0f, 108, 48)];

    /* Set the title of the button */

    [button setTitle:@"Stretched Image on Button"

                 forState:UIControlStateNormal];

    /* Adjust the font for our text */

    button.titleLabel.font = [UIFont systemFontOfSize:15.0f];

    return button;

    

}


-(UIButton *)getstretchButton

{

    UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom];

    [button setFrame:CGRectMake(0.0f, 0.0f, 300, 200)];

    /* Set the title of the button */

    [button setTitle:@"Stretched Image on Button"

            forState:UIControlStateNormal];

    /* Adjust the font for our text */

    button.titleLabel.font = [UIFont systemFontOfSize:15.0f];

    return button;

    

}



-(void)testresizableImageWithCapInsets

{

    

    UIButton* button = [self getButton];

    UIImage * image = [UIImage imageNamed:@"button2"];

    [button setBackgroundImage:image forState:UIControlStateNormal];

    [self.view addSubview:button];

    button.centerCGPointMake(self.view.center.x, self.view.center.y - 100);

    

    UIButton * stretchButton = [self getstretchButton];

    UIEdgeInsets edgeInsets;

    edgeInsets.left = 40.0f;

    edgeInsets.top = 13;

    edgeInsets.right =40.0f;

    edgeInsets.bottom = 10;

    //平铺

    UIImage * stretchImage = [image resizableImageWithCapInsets:edgeInsets resizingMode:UIImageResizingModeTile];

    //拉伸

//    UIImage * stretchImage = [image resizableImageWithCapInsets:edgeInsets resizingMode:UIImageResizingModeStretch];

    [stretchButton setBackgroundImage:stretchImage forState:UIControlStateNormal];

    [self.view addSubview:stretchButton];

    stretchButton.centerCGPointMake(self.view.center.x, self.view.center.y + 100);

    

}


@end


原始图:


运行后:



使用拉伸的效果


20.6. Drawing Lines

划线

CGContextMoveToPoint

CGContextAddLineToPoint

- (void)testdraw

{

    [self drawRooftopAtTopPointof:CGPointMake(160.0f, 40.0f)

                    textToDisplay:@"Miter"

                         lineJoin:kCGLineJoinMiter];

    [self drawRooftopAtTopPointof:CGPointMake(160.0f, 180.0f)

                    textToDisplay:@"Bevel"

                         lineJoin:kCGLineJoinBevel];

    [self drawRooftopAtTopPointof:CGPointMake(160.0f, 320.0f)

                    textToDisplay:@"Round"

                         lineJoin:kCGLineJoinRound];

}


- (void) drawRooftopAtTopPointof:(CGPoint)paramTopPoint

                   textToDisplay:(NSString *)paramText

                        lineJoin:(CGLineJoin)paramLineJoin{

    /* Set the color that we want to use to draw the line */

    [[UIColor brownColor] set];

    /* Get the current graphics context */

    CGContextRef currentContext = UIGraphicsGetCurrentContext();

    /* Set the line join */

    CGContextSetLineJoin(currentContext,

                         paramLineJoin);

    /* Set the width for the lines */

    CGContextSetLineWidth(currentContext,

                          20.0f);

    /* Start the line at this point */

    CGContextMoveToPoint(currentContext,

                         paramTopPoint.x - 140,

                         paramTopPoint.y + 100);

    /* And end it at this point */

    CGContextAddLineToPoint(currentContext,

                            paramTopPoint.x,

                            paramTopPoint.y);

    /* Extend the line to another point to

     make the rooftop */

    CGContextAddLineToPoint(currentContext,

                            paramTopPoint.x + 140,

                            paramTopPoint.y + 100);

    /* Use the context's current color to draw the lines */

    CGContextStrokePath(currentContext);

    /* Draw the text in the rooftop using a black color */

    [[UIColor blackColor] set];

    /* Now draw the text */

    CGPoint drawingPoint = CGPointMake(paramTopPoint.x - 40.0f,

                                       paramTopPoint.y + 60.0f);

    UIFont *font = [UIFont boldSystemFontOfSize:30.0f];

    [paramText drawAtPoint:drawingPoint

            withAttributes:@{NSFontAttributeName : font}];

}



20.7. Constructing Paths

构建路径


#import "View.h"


@implementation View


- (id)initWithFrame:(CGRect)frame

{

    self = [super initWithFrame:frame];

    if (self) {

        // Initialization code

    }

    return self;

}

- (void)drawRect:(CGRect)rect{

    /* Create the path */

    CGMutablePathRef path = CGPathCreateMutable();

    /* How big is our screen? We want the X to cover the whole screen */

    CGRect screenBounds = [[UIScreen mainScreen] bounds];

    /* Start from top-left */

    CGPathMoveToPoint(path,

                      NULL,

                      screenBounds.origin.x,

                      screenBounds.origin.y);

    /* Draw a line from top-left to bottom-right of the screen */

    CGPathAddLineToPoint(path,

                         NULL,

                         screenBounds.size.width,

                         screenBounds.size.height);

    /* Start another line from top-right */

    CGPathMoveToPoint(path,

                      NULL,

                      screenBounds.size.width,

                      screenBounds.origin.y);

    /* Draw a line from top-right to bottom-left */

    CGPathAddLineToPoint(path,

                         NULL,

                         screenBounds.origin.x,

                         screenBounds.size.height);

    /* Get the context that the path has to be drawn on */

    CGContextRef currentContext = UIGraphicsGetCurrentContext();

    /* Add the path to the context so we can

     draw it later */

    CGContextAddPath(currentContext,

                     path);

    /* Set the blue color as the stroke color */

    [[UIColor blueColor] setStroke];

    /* Draw the path with stroke color */

    CGContextDrawPath(currentContext,

                      kCGPathStroke);

    /* Finally release the path object */

    CGPathRelease(path);

}

@end



20.8. Drawing Rectangles

画矩形


- (void)drawRect:(CGRect)rect{

    /* Create the path first. Just the path handle. */

    CGMutablePathRef path = CGPathCreateMutable();

    

    CGRect rectangle = CGRectMake(200.0f,

                                  330.0f,

                                  100.0f,

                                  100.0f);

    /* Add the rectangle to the path */

    CGPathAddRect(path,

                  NULL,

                  rectangle);

    /* Here are our first rectangle boundaries */

    

    CGRect rectangle1 = CGRectMake(10.0f,

                                   30.0f,

                                   200.0f,

                                   300.0f);

    /*And the second rectangle */

    CGRect rectangle2 = CGRectMake(40.0f,

                                   100.0f,

                                   90.0f,

                                   300.0f);

    /* Put both rectangles into an array */

    CGRect rectangles[2] = {

        rectangle1, rectangle2

    };

    /* Add the rectangles to the path */

    CGPathAddRects(path,

                   NULL,

                   (const CGRect *)&rectangles, 2);

    /* Get the handle to the current context */

    CGContextRef currentContext = UIGraphicsGetCurrentContext();

    /* Add the path to the context */

    CGContextAddPath(currentContext,

                     path);

    /* Set the fill color to cornflower blue */

    [[UIColor colorWithRed:0.20f

                     green:0.60f

                      blue:0.80f

                     alpha:1.0f] setFill];

    /* Set the stroke color to black */

    [[UIColor blackColor] setStroke];

    /* Set the line width (for the stroke) to 5 */

    CGContextSetLineWidth(currentContext,

                          5.0f);

    /* Stroke and fill the path on the context */

    CGContextDrawPath(currentContext,

                      kCGPathFillStroke);

    /* Dispose of the path */

    CGPathRelease(path);

}


结果:


20.9. Adding Shadows to Shapes

阴影

来画两个矩形,第一个要阴影,第二个不要阴影

- (void) drawRect:(CGRect)rect{

    [self drawRectAtTopOfScreen];

    [self drawRectAtBottomOfScreen];

}

- (void) drawRectAtTopOfScreen{

    /* Get the handle to the current context */

    CGContextRef currentContext = UIGraphicsGetCurrentContext();

    CGContextSetShadowWithColor(currentContext,

                                CGSizeMake(10.0f, 10.0f),

                                20.0f,

                                [[UIColor grayColor] CGColor]);

    /* Create the path first. Just the path handle. */

    CGMutablePathRef path = CGPathCreateMutable();

    /* Here are our rectangle boundaries */

    CGRect firstRect = CGRectMake(55.0f,

                                  60.0f,

                                  150.0f,

                                  150.0f);

    /* Add the rectangle to the path */

    CGPathAddRect(path,

                  NULL,

                  firstRect);

    /* Add the path to the context */

    CGContextAddPath(currentContext,

                     path);

    /* Set the fill color to cornflower blue */

    [[UIColor colorWithRed:0.20f

                     green:0.60f

                      blue:0.80f

                     alpha:1.0f] setFill];

    /* Fill the path on the context */

    CGContextDrawPath(currentContext,

                      kCGPathFill);

    /* Dispose of the path */

    CGPathRelease(path);

}

- (void) drawRectAtBottomOfScreen{

    /* Get the handle to the current context */

    CGContextRef currentContext = UIGraphicsGetCurrentContext();

    CGMutablePathRef secondPath = CGPathCreateMutable();

    CGRect secondRect = CGRectMake(150.0f,

                                   250.0f,

                                   100.0f,

                                   100.0f);

    CGPathAddRect(secondPath,

                  NULL,

                  secondRect);

    CGContextAddPath(currentContext,

                     secondPath);

    [[UIColor purpleColor] setFill];

    CGContextDrawPath(currentContext,

                      kCGPathFill);

    CGPathRelease(secondPath);

}

运行:


我们发现,第二个也有阴影了,这是因为在画第一个的时候,其改变的属性应用到第二个上面了。

如何让第二个没有阴影呢?

方法一:先画第二个,再画第一个,不过这方法比较山寨

方法二:再画第一个之前先把graphics context的状态保存,画完之后再恢复回去。

- (void) drawRectAtTopOfScreen{

    /* Get the handle to the current context */

    CGContextRef currentContext = UIGraphicsGetCurrentContext();

    CGContextSaveGState(currentContext);

    CGContextSetShadowWithColor(currentContext,

                                CGSizeMake(10.0f, 10.0f),

                                20.0f,

                                [[UIColor grayColor] CGColor]);

    /* Create the path first. Just the path handle. */

    CGMutablePathRef path = CGPathCreateMutable();

    /* Here are our rectangle boundaries */

    CGRect firstRect = CGRectMake(55.0f,

                                  60.0f,

                                  150.0f,

                                  150.0f);

    /* Add the rectangle to the path */

    CGPathAddRect(path,

                  NULL,

                  firstRect);

    /* Add the path to the context */

    CGContextAddPath(currentContext,

                     path);

    /* Set the fill color to cornflower blue */

    [[UIColor colorWithRed:0.20f

                     green:0.60f

                      blue:0.80f

                     alpha:1.0f] setFill];

    /* Fill the path on the context */

    CGContextDrawPath(currentContext,

                      kCGPathFill);

    /* Dispose of the path */

    CGPathRelease(path);

    /* Restore the context to how it was

     when we started */

    CGContextRestoreGState(currentContext);

}




20.10. Drawing Gradients

渐变颜色

CGGradientCreateWithColor


- (void)drawRect:(CGRect)rect{

    CGContextRef currentContext = UIGraphicsGetCurrentContext();

    CGContextSaveGState(currentContext);

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

    UIColor *startColor = [UIColor orangeColor];

    CGFloat *startColorComponents =

    (CGFloat *)CGColorGetComponents([startColor CGColor]);

    UIColor *endColor = [UIColor blueColor];

    CGFloat *endColorComponents =

    (CGFloat *)CGColorGetComponents([endColor CGColor]);

    CGFloat colorComponents[8] = {

        /* Four components of the orange color (RGBA) */

        startColorComponents[0],

        startColorComponents[1],

        startColorComponents[2],

        startColorComponents[3], /* First color = orange */

        /* Four components of the blue color (RGBA) */

        endColorComponents[0],

        endColorComponents[1],

        endColorComponents[2],

        endColorComponents[3], /* Second color = blue */

    };

    CGFloat colorIndices[2] = {

        0.0f, /* Color 0 in the colorComponents array */

        1.0f, /* Color 1 in the colorComponents array */

    };

    CGGradientRef gradient = CGGradientCreateWithColorComponents

    (colorSpace,

     (const CGFloat *)&colorComponents,

     (const CGFloat *)&colorIndices,

     2);

    CGColorSpaceRelease(colorSpace);

    CGPoint startPoint, endPoint;

    startPoint = CGPointMake(120,

                             260);

    endPoint = CGPointMake(200.0f,

                           220);

//    startPoint = CGPointMake(50, 50);

//    endPoint = CGPointMake(270, 430);

    CGContextDrawLinearGradient (currentContext,

                                 gradient,

                                 startPoint,

                                 endPoint,

                                 kCGGradientDrawsBeforeStartLocation |//自己换成0试试

                                 kCGGradientDrawsAfterEndLocation);

    CGGradientRelease(gradient);

    CGContextRestoreGState(currentContext);

}


运行:





20.11. Moving Shapes Drawn on Graphic Contexts

移动所画的内容

CGAffineTransformMakeTranslation

- (void)drawRect:(CGRect)rect{

    /* Create the path first. Just the path handle. */

    CGMutablePathRef path = CGPathCreateMutable();

    /* Here are our rectangle boundaries */

    CGRect rectangle = CGRectMake(10.0f,

                                  30.0f,

                                  200.0f,

                                  300.0f);

    /* We want to displace the rectangle to the right by

     100 points but want to keep the y position

     untouched */

    CGAffineTransform transform1 = CGAffineTransformMakeTranslation(100.0f,

                                                                   0.0f);

    CGAffineTransform transform2 = CGAffineTransformMakeRotation(0.1);

    CGAffineTransform transform = CGAffineTransformConcat(transform1, transform2);

    NSLog(@"transform1=%@", NSStringFromCGAffineTransform(transform1));

    NSLog(@"transform2=%@", NSStringFromCGAffineTransform(transform2));

    NSLog(@"transform=%@", NSStringFromCGAffineTransform(transform));


    /* Add the rectangle to the path */

    CGPathAddRect(path,

                  &transform,

                  rectangle);

    /* Get the handle to the current context */

    CGContextRef currentContext = UIGraphicsGetCurrentContext();

    /* Add the path to the context */

    CGContextAddPath(currentContext, path);

    /* Set the fill color to cornflower blue */

    [[UIColor colorWithRed:0.20f

                     green:0.60f

                      blue:0.80f

                     alpha:1.0f] setFill]; /* Set the stroke color to brown */

    [[UIColor brownColor] setStroke];

    /* Set the line width (for the stroke) to 5 */

    CGContextSetLineWidth(currentContext,5.0f);

    /* Stroke and fill the path on the context */

    CGContextDrawPath(currentContext,kCGPathFillStroke);

    /* Dispose of the path */

    CGPathRelease(path);

}

运行

2014-08-06 15:45:51.579 cookbook7_20[647:a0b] transform=[1, 0, 0, 1, 100, 0]



20.12. Scaling Shapes Drawn on Graphic Contexts

- (void)drawRect:(CGRect)rect{

    /* Create the path first. Just the path handle. */

    CGMutablePathRef path = CGPathCreateMutable();

    /* Here are our rectangle boundaries */

    CGRect rectangle = CGRectMake(10.0f,

                                  30.0f,

                                  200.0f,

                                  300.0f);

    /* We want to displace the rectangle to the right by

     100 points but want to keep the y position

     untouched */

//    CGAffineTransform transform = CGAffineTransformMakeTranslation(100.0f,

//                                                                   0.0f);

    /* Scale the rectangle to half its size */

    CGAffineTransform transform = CGAffineTransformMakeScale(0.5f, 0.5f);

    /* Add the rectangle to the path */

    CGPathAddRect(path,

                  &transform,

                  rectangle);

    NSLog(@"transform=%@", NSStringFromCGAffineTransform(transform));


    /* Add the rectangle to the path */

    CGPathAddRect(path,

                  &transform,

                  rectangle);

    /* Get the handle to the current context */

    CGContextRef currentContext = UIGraphicsGetCurrentContext();

    /* Add the path to the context */

    CGContextAddPath(currentContext, path);

    /* Set the fill color to cornflower blue */

    [[UIColor colorWithRed:0.20f

                     green:0.60f

                      blue:0.80f

                     alpha:1.0f] setFill]; /* Set the stroke color to brown */

    [[UIColor brownColor] setStroke];

    /* Set the line width (for the stroke) to 5 */

    CGContextSetLineWidth(currentContext,5.0f);

    /* Stroke and fill the path on the context */

    CGContextDrawPath(currentContext,kCGPathFillStroke);

    /* Dispose of the path */

    CGPathRelease(path);

}

运行:

2014-08-06 15:53:11.857 cookbook7_20[713:a0b] transform=[0.5, 0, 0, 0.5, 0, 0]


- (void)drawRect:(CGRect)rect{

    /* Create the path first. Just the path handle. */

    CGMutablePathRef path = CGPathCreateMutable();

    /* Here are our rectangle boundaries */

    CGRect rectangle = CGRectMake(10.0f,

                                  30.0f,

                                  200.0f,

                                  300.0f);

    /* Add the rectangle to the path */

    CGPathAddRect(path,

                  NULL,

                  rectangle);

    /* Get the handle to the current context */

    CGContextRef currentContext = UIGraphicsGetCurrentContext();

    /* Scale everything drawn on the current

     graphics context to half its size */

    CGContextScaleCTM(currentContext,

                      0.5f,

                      0.5f);

    /* Add the path to the context */

    CGContextAddPath(currentContext,

                     path);

    /* Set the fill color to cornflower blue */

    [[UIColor colorWithRed:0.20f

                     green:0.60f

                      blue:0.80f

                     alpha:1.0f] setFill]; /* Set the stroke color to brown */

    [[UIColor brownColor] setStroke];

    /* Set the line width (for the stroke) to 5 */

    CGContextSetLineWidth(currentContext,

                          5.0f);

    /* Stroke and fill the path on the context */

    CGContextDrawPath(currentContext,

                      kCGPathFillStroke);

    /* Dispose of the path */

    CGPathRelease(path);

}


运行:


20.13. Rotating Shapes Drawn on Graphic Contexts

CGAffineTransformMakeRotation

- (void)drawRect:(CGRect)rect{

    /* Create the path first. Just the path handle. */

    CGMutablePathRef path = CGPathCreateMutable();

    /* Here are our rectangle boundaries */

    CGRect rectangle = CGRectMake(10.0f,

                                  30.0f,

                                  200.0f,

                                  300.0f);

    /* Rotate the rectangle 45 degrees clockwise */

    CGAffineTransform transform =

    CGAffineTransformMakeRotation((45.0f * M_PI) / 180.0f);

    /* Add the rectangle to the path */

    CGPathAddRect(path,

                  &transform,

                  rectangle);

    NSLog(@"transform=%@", NSStringFromCGAffineTransform(transform));


    /* Add the rectangle to the path */

    CGPathAddRect(path,

                  &transform,

                  rectangle);

    /* Get the handle to the current context */

    CGContextRef currentContext = UIGraphicsGetCurrentContext();

    /* Add the path to the context */

    CGContextAddPath(currentContext, path);

    /* Set the fill color to cornflower blue */

    [[UIColor colorWithRed:0.20f

                     green:0.60f

                      blue:0.80f

                     alpha:1.0f] setFill]; /* Set the stroke color to brown */

    [[UIColor brownColor] setStroke];

    /* Set the line width (for the stroke) to 5 */

    CGContextSetLineWidth(currentContext,5.0f);

    /* Stroke and fill the path on the context */

    CGContextDrawPath(currentContext,kCGPathFillStroke);

    /* Dispose of the path */

    CGPathRelease(path);

}

运行:


2014-08-06 16:01:13.445 cookbook7_20[732:a0b] transform=[0.70710677, 0.70710677, -0.70710677, 0.70710677, 0, 0]







20.14. Animating and Moving Views


- (void)viewDidLoad

{

    [super viewDidLoad];

// Do any additional setup after loading the view, typically from a nib.

//    [self testresizableImageWithCapInsets];

//    [self testdraw];

    UIImage *xcodeImage = [UIImage imageNamed:@"Xcode"];

    self.xcodeImageView = [[UIImageView alloc]

                           initWithImage:xcodeImage];

    /* Just set the size to make the image smaller */

    [self.xcodeImageView setFrame:CGRectMake(0.0f,

                                             30.0f,

                                             100.0f,

                                             100.0f)];

    self.view.backgroundColor = [UIColor whiteColor];

    [self.view addSubview:self.xcodeImageView];

}

- (void) viewDidAppear:(BOOL)paramAnimated{

    [super viewDidAppear:paramAnimated];

    /* Start from top left corner */

    [self.xcodeImageView setFrame:CGRectMake(0.0f,

                                             30.0f,

                                             100.0f,

                                             100.0f)];

    [UIView beginAnimations:@"xcodeImageViewAnimation" context:(__bridge void *)self.xcodeImageView];

    /* 5 seconds animation */

    [UIView setAnimationDuration:5.0f];

    /* Receive animation delegates */

    [UIView setAnimationDelegate:self];

    [UIView setAnimationDidStopSelector:@selector(imageViewDidStop:finished:context:)];

    CGRect endRect;

    endRect.origin.x = self.view.bounds.size.width - 100;

    endRect.origin.y = self.view.bounds.size.height - 100;

    endRect.size = CGSizeMake(100.0f, 100.0f);

    /* End at the bottom right corner */

    [self.xcodeImageView setFrame:endRect];

    [UIView commitAnimations];

}

- (void)imageViewDidStop:(NSString *)paramAnimationID

                finished:(NSNumber *)paramFinished

                 context:(void *)paramContext{

    NSLog(@"Animation finished.");

    NSLog(@"Animation ID = %@", paramAnimationID);

    UIImageView *contextImageView = (__bridge UIImageView *)paramContext;

    NSLog(@"Image View = %@", contextImageView);

}

运行:

2014-08-06 17:10:46.763 cookbook7_20[979:a0b] Animation finished.

2014-08-06 17:10:46.764 cookbook7_20[979:a0b] Animation ID = xcodeImageViewAnimation

2014-08-06 17:10:46.766 cookbook7_20[979:a0b] Image View = <UIImageView: 0x89673e0; frame = (220 380; 100 100); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x8965440>> - (null)


图片从左上角慢慢移动到右下角。


不知道书上为什么没介绍这个,感觉更喜欢用下面这个

- (void) viewDidAppear:(BOOL)paramAnimated{

    [super viewDidAppear:paramAnimated];

    /* Start from top left corner */

    [self.xcodeImageView setFrame:CGRectMake(0.0f,

                                             30.0f,

                                             100.0f,

                                             100.0f)];

    [UIView animateWithDuration:5.0f animations:^{

        CGRect endRect;

        endRect.origin.x = self.view.bounds.size.width - 100;

        endRect.origin.y = self.view.bounds.size.height - 100;

        endRect.size = CGSizeMake(100.0f, 100.0f);

        /* End at the bottom right corner */

        [self.xcodeImageView setFrame:endRect];

    } completion:^(BOOL finished) {

        NSLog(@"finished");

    }];

}

效果一样


20.15. Animating and Scaling Views

- (void)viewDidLoad

{

    [super viewDidLoad];

// Do any additional setup after loading the view, typically from a nib.


    UIImage *xcodeImage = [UIImage imageNamed:@"Xcode"];

    self.xcodeImageView = [[UIImageView alloc]

                           initWithImage:xcodeImage];

    /* Just set the size to make the image smaller */

    [self.xcodeImageView setFrame:CGRectMake(0.0f,

                                             30.0f,

                                             100.0f,

                                             100.0f)];

    self.view.backgroundColor = [UIColor whiteColor];

    [self.view addSubview:self.xcodeImageView];

}

#if 1

- (void) viewDidAppear:(BOOL)paramAnimated{

    [super viewDidAppear:paramAnimated];

    /* Place the image view at the center of the view of this view controller */

    self.xcodeImageView.center = self.view.center;

    /* Make sure no translation is applied to this image view */

    self.xcodeImageView.transform = CGAffineTransformIdentity;

    /* Begin the animation */

    [UIView beginAnimations:nil

                    context:NULL];

    /* Make the animation 5 seconds long */

    [UIView setAnimationDuration:5.0f];

    /* Make the image view twice as large in

                                         width and height */

    self.xcodeImageView.transform = CGAffineTransformMakeScale(2.0f,

                                                               2.0f);

    /* Commit the animation */

    [UIView commitAnimations];

}

#else  //或者这个也行

- (void) viewDidAppear:(BOOL)paramAnimated{

    [super viewDidAppear:paramAnimated];

    /* Place the image view at the center of the view of this view controller */

    self.xcodeImageView.center = self.view.center;

    /* Make sure no translation is applied to this image view */

    self.xcodeImageView.transform = CGAffineTransformIdentity;

    

    [UIView animateWithDuration:5.0f animations:^{

        self.xcodeImageView.transform = CGAffineTransformMakeScale(2.0f, 2.0f);

    }];

}

#endif



20.16. Animating and Rotating Views

- (void)viewDidLoad

{

    [super viewDidLoad];

// Do any additional setup after loading the view, typically from a nib.


    UIImage *xcodeImage = [UIImage imageNamed:@"Xcode"];

    self.xcodeImageView = [[UIImageView alloc]

                           initWithImage:xcodeImage];

    /* Just set the size to make the image smaller */

    [self.xcodeImageView setFrame:CGRectMake(0.0f,

                                             30.0f,

                                             100.0f,

                                             100.0f)];

    self.view.backgroundColor = [UIColor whiteColor];

    [self.view addSubview:self.xcodeImageView];

}


- (void) viewDidAppear:(BOOL)paramAnimated{

    [super viewDidAppear:paramAnimated];

    self.xcodeImageView.center = self.view.center;

    /* Begin the animation */

    [UIView beginAnimations:@"clockwiseAnimation"

                    context:NULL];

    /* Make the animation 5 seconds long */

    [UIView setAnimationDuration:5.0f];

    [UIView setAnimationDelegate:self];

    [UIView setAnimationDidStopSelector: @selector(clockwiseRotationStopped:finished:context:)];

    /* Rotate the image view 90 degrees */

    self.xcodeImageView.transform = CGAffineTransformMakeRotation((90.0f * M_PI) / 180.0f);

    /* Commit the animation */

    [UIView commitAnimations];

}


- (void)clockwiseRotationStopped:(NSString *)paramAnimationID

                        finished:(NSNumber *)paramFinished

                         context:(void *)paramContext{

    [UIView beginAnimations:@"counterclockwiseAnimation"

                    context:NULL];

    /* 5 seconds long */

    [UIView setAnimationDuration:5.0f];

    /* Back to original rotation */

    self.xcodeImageView.transform = CGAffineTransformIdentity;

    [UIView commitAnimations];

}

运行:


先顺时针旋转90度后,在逆时针旋转90


20.17. Capturing a Screenshot of Your View into an Image

抓图

- (void) viewDidAppear:(BOOL)animated{

    [super viewDidAppear:animated];

    /* Capture the screenshot */

    UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, YES, 0.0f);

    //提示没这个方法drawViewHierarchyInRect-_-!

    if ([self.view drawViewHierarchyInRect:self.view.bounds]){

        NSLog(@"Successfully draw the screenshot.");

    } else {

        NSLog(@"Failed to draw the screenshot.");

    }

    UIImage *screenshot = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    

    /* Save it to disk */

    NSFileManager *fileManager = [[NSFileManager alloc] init];

    NSURL *documentsFolder = [fileManager URLForDirectory:NSDocumentDirectory

                                                 inDomain:NSUserDomainMask

                                        appropriateForURL:nil

                                                   create:YES

                                                    error:nil];

    NSURL *screenshotUrl = [documentsFolder URLByAppendingPathComponent:@"screenshot.png"];

    

    NSData *screenshotData = UIImagePNGRepresentation(screenshot);

    if ([screenshotData writeToURL:screenshotUrl atomically:YES]){

        NSLog(@"Successfully saved screenshot to %@", screenshotUrl);

    } else {

        NSLog(@"Failed to save screenshot.");

    }

}


提示没这个方法drawViewHierarchyInRect:

用例执行不了-_-!



   






















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值