iOS Core Animation--寄宿图

一、寄宿图–contents属性
(1) CALayer有一个属性叫contents,contents默认可以传一个id类型的对象,但是只有你传CGImage的时候,它才能够正常显示在屏幕上。所以最终我们的图形渲染落点落在contents身上如图。

注意:如果你想将UIImage类型的图赋值给contents,你可以使用下面的方法: layer.contents = (__bridge id)image.CGImage;
( 解释:因为,我们赋值的类型是CGImageRef,它是指向CGImage指针,UIImage有一个CGImage属性,它返回CGImageRef类型,但直接将其赋值给CAlayer的contents会出错,因为CGImageRef是属于Core Foundation类型,应使用Bridge)
例如:

    //给view设置一张图片—方法是操作图层添加图片
    UIImage *image = [UIImage imageNamed:@"w.jpg"];
    view.layer.contents = (__bridge id)(image.CGImage);

(2)设置图层内容的几个属性
contentsGravity:设置内容在图层边界怎样对齐;
如果是等比例拉伸图片使用UIViewContentModeScaleAspectFit。UIView大多数与视觉相关的属性比如contentMode,对这些视觉属性的操作其实是对图层的操作;图层的contentsGravity是与contentMode对应的属性,它是NSString类型。
这里写图片描述

contentsScale:定义了寄宿图的像素尺寸和视图大小的比例,默认为1.0;其实该属性是支持高分辨机制的一部分,用来判断在绘制图层的时候应该为寄宿图创建空间的大小和需要显示的图片的拉伸度。对应的UIView有一个很少用到的属性是contentScaleFactor(如果值为1.0,将会以每个点1像素绘制图片;如果为2.0,将会以每个点2像素绘制图片,就是Retina屏)

  注意:conentsScale属性受contentsGravity的影响。如果设置contentsGravity,表示图片已被拉伸;此时设置图层的contentsScale会没有任何影响

makeToBounds:用于决定是否沿边界裁剪只显示边框中的内容,YES表示只显示边界内的图片,UIView对应的属性是clipsToBounds

contentsRect:用于显示图层的寄宿图的一个子域,默认为{0,0,1,1},显示全部寄宿图;

这里写图片描述

注意:contentsRect使用的是单位坐标,单位坐标指定在0~1之间,是相对值。下面是点、像素、单位的介绍

这里写图片描述

contentsCenter:它是CGRect类型,定义了一个固定的边框和一个在图层上可拉伸的区域。默认contentsCenter是{0,0,1,1},这意味着如果大小(由contentsGravity)改变了,寄宿图将会均匀的拉伸开。他的效果和UIImage中的-resizableImageWithCapInsets:方法类似。

下面是我们增加原点值并减小尺寸的效果
这里写图片描述

二、自定义绘制图层Custom Drawing

当视图出现在屏幕上的时候,-drawRect:是被自动调用的。-drawRect:中的代码利用Core Graphics绘制寄宿图,然后将内容缓存起来用于以后的更新。所以虽然-drawRect:是UIView的方法,但是实际上底层的CALayer进行重绘工作,然后保存产生的图片

 使用Core Graphics直接绘制寄宿图,通过继承UIView并实现-drawRect:方法来自定义绘制。一旦UIView中检测到重写了-drawRect:方法,UIView就会为视图分配一个寄宿图,寄宿图的像素尺寸=视图大小*contentsScale的值;
  所以不需要寄宿图,尽量不要重写-drawRect:方法,因为给它分配寄宿图会大量消耗CPU资源和内存的。

CALayer有一个可选的delegate属性,实现CALayerDelegate协议,但是这个协议是非正式协议,即没有CALayerDelegate @protocol可以让我们引用。我们只需调用我们想调用的方法,剩下的CALayer会处理。但一般UIVIew创建宿主图层之后,就会将图层的delegate设置为他自己。提供一个dispayerLayer:的实现。

需要重绘时调用-(void)displayLayer:(CALayerCALayer *)layer;
CALayer会请求他的代理给它一个寄宿图,在这个方法中代理可以设置contents属性

如果没有实现-displayLayer:方法,CALayer会创建空的寄宿图和一个Core Graphics的绘制上下文环境作为ctx参数传入;然后,调用
-(void)drawLayer:(CALayer *)layer inContext:(CGContexRef)ctx;

 但实际使用时,一般使用寄宿了视图的图层,不必实现-displayLayer:和-drawLayer:inContext:方法绘制寄宿图。通常实现UIView的-drawRect:方法,其他的UIView会包揽全部工作

注意:(1)当图层显示在屏幕上时,CALayer不会自动重绘,而是由开发者决定绘制,通过调用-display函数开始重回
(2)没使用masksToBounds,图形也会沿边界裁剪,因为CALayerDelegate没有对超出边界外的内容提供绘制支持

- (void)viewDidLoad {
    [super viewDidLoad];

    //创建子图层
    CALayer *blueLayer = [CALayer layer];
    blueLayer.frame    = CGRectMake(50.0f, 50.0f, 100.0f, 100.0f);
    blueLayer.backgroundColor = [UIColor blueColor].CGColor;

    //设置controller为layer的代理
    blueLayer.delegate = self;

    //确保背景图片的图层使用正确的scale
    blueLayer.contentsScale = [UIScreen mainScreen].scale;
    [self.view.layer addSublayer:blueLayer];


    //强制重画图层,当图层显示在屏幕上时,CALyer不会自动重绘,而是由开发者决定绘制
    [blueLayer display];


}



-(void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx{

    //画一个红色的圆
    CGContextSetLineWidth(ctx, 10);
    CGContextSetStrokeColorWithColor(ctx, [UIColor redColor].CGColor);
    //在指定区域画一个椭圆,并充满这个空间
    CGContextStrokeEllipseInRect(ctx, layer.frame);

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
iOS开发中上传片可以采用以下步骤: 1.选择要上传的片,可以使用系统提供的UIImagePickerController控制器,或者使用第三方库,例如TZImagePickerController。 2.将选中的片转换为NSData格式。 3.使用NSURLSession或AFNetworking等网络库,将片数据上传到服务器。 以下是一个简单的上传片的示例代码: ``` // 选择片 UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init]; imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; imagePicker.delegate = self; [self presentViewController:imagePicker animated:YES completion:nil]; // 将选中的片转换为NSData格式 - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<UIImagePickerControllerInfoKey,id> *)info { UIImage *selectedImage = info[UIImagePickerControllerOriginalImage]; NSData *imageData = UIImageJPEGRepresentation(selectedImage, 0.5); // 上传片到服务器 NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration]; NSURL *url = [NSURL URLWithString:@"http://example.com/upload.php"]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; request.HTTPMethod = @"POST"; NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request fromData:imageData completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { // 处理服务器返回的响应 }]; [uploadTask resume]; [picker dismissViewControllerAnimated:YES completion:nil]; } ``` 其中,upload.php是服务器端接收片的脚本文件。在服务器端,可以使用PHP等语言来处理上传的片数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员的修养

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值