IOS core Animation: CALayer (1): ios core animation calayer

Source: Internet
Author: User

IOS core Animation: CALayer (1): ios core animation calayer

Relationship between UIView and CALayer
In iOS, A UIView corresponds to a CALayer. The role of a view is to create and manage this layer to ensure that the child view is added or removed from the hierarchy, their associated layers also correspond to the same operations in the hierarchical relationship tree. in fact, the associated layers are actually used for display and animation on the screen. UIView is only an encapsulation of IT and provides some iOS functions similar to processing touch, and advanced interfaces of Core Animation underlying methods. (CALayer does not respond to events. It provides several layers that can be used to determine a contact)

Significance of CALayer
The two parallel layers CALayer and UIView should be provided. On the one hand, duties can be separated to avoid a lot of repeated code. On the other hand, the interface between iOS and Mac OS is not very different, however, because iOS's multi-touch user interface is essentially different from Mac's mouse and keyboard-based user interface, a common CALayer is provided to provide interfaces, and UIView and NSView are provided to provide events respectively.

Use of CALayer
We usually use UIView in this way:

1 let blueView = UIView(frame: CGRectMake(100, 100, 100, 100))2 blueView.backgroundColor = UIColor.blueColor()3 self.view.addSubview(blueView)

But we can use CALayer in this way, and you can directly replace the Code with the following section. The program will not have any difference in appearance.

1 let blueLayer = CALayer()2 blueLayer.frame = CGRectMake(100, 100, 100, 100)3 blueLayer.backgroundColor = UIColor.blueColor().CGColor4 self.view.layer.addSublayer(blueLayer)

CALayer content (contents) related attributes
Contents attributes
Layer has a contents attribute. It needs to input an id (AnyObject !) Type. This is because it requires CGImage on the iOS platform, while Mac requires NSImage. In OC, you need to use the id type to convert it, in Swift, you only need to assign a CGImage directly, because any Class object can be assigned to AnyObject. If you input other objects, the program will not report an error, however, the image is not displayed, and the contents attribute is also used for UIImageView to display the image.

ContentGravity attributes
The contentGravity attribute corresponds to the contentMode attribute of the view, which can control how the layer maps and stretches. Although its value is a string, swift provides it with a constant string to match each string.

ContentsScale attributes
The contentsScale attribute corresponds to the contentScaleFactor in the UIView. It determines the ratio of an image to a view, that is, the display of several pixels at a point on the screen. This is the principle of screen adaptation for iOS devices, A UIImage contains scale, ction, and other information. Converting to CGImage will lose this information. You can use the contentsScale attribute to convert the image. set scale to it.

MaskToBounds attributes
The maskToBounds attribute corresponds to the masksToBounds attribute of CALayer. If it is set to true, the image is cropped externally.

ContentsRect attributes
The contentsRect attribute allows us to display part of an image in a layer. The cropping area of this image is this attribute, which is a CGRect, you can combine images (that is, you can combine a set of images into an image, crop the image, and then use it ), in this way, the memory usage, loading time, and rendering performance are advantageous. The value of this parameter is proportional, and the maximum value is 1.

ContentsCenter attributes
The contentsCenter attribute corresponds to the resizableImageWithCapInsets of UIImage. Its value is a CGRect, which represents the enlarged area. Its effect is that when the party contentScale is enlarged, only the contentsCenter area is enlarged, and other areas are compressed.

IOS plotting
CGImage is not unique and can be assigned to the contents attribute. You can also use Core Graphics to draw a boarding graph for it. If you implement the drawRect method, then, if you call setNeedsDisplay or the appearance attribute is changed, it will automatically call drawRect for automatic re-painting, although drawRet is a UIView method, however, the underlying layers all use CALayer to redraw and save images. If you do not need custom plotting, do not write an empty drawRect method, which consumes cpu and memory resources.
CALayer has an optional delegate attribute. If delegate is set and the layer's displey method is called proactively (note that the re-painting time is different from that of drawRect, you can also call the setNeedsDisplay method to find the time for the system to call.) It will call displayLayer (layer: CALayer !) Method. Here is the last chance to set the contents attribute. If you do not implement this method, it will try to call the following method: drawLayer (layer: CALayer !, InContext ctx: CGContext !), If you implement the displayLayer method, the following method will not be called. In the drawLayer method, you can plot

1 override func drawLayer(layer: CALayer!, inContext ctx: CGContext!) {2     CGContextSetLineWidth(ctx, 10.0)3     CGContextSetStrokeColorWithColor(ctx, UIColor.redColor().CGColor);4     CGContextStrokeEllipseInRect(ctx, layer.bounds)d0605579435 }6 override func displayLayer(layer: CALayer!) {7     layer.contents = UIImage(named: "11.png")?.CGImage8 }

Since a UIView sets its corresponding CALayer delegate as its own, you cannot set another layer's delegate as it, And the drawRect method is used in the UIView, however, the use of delegate can only use one layer separately.

Layer Geometry

The frame/bounds/center of UIView corresponds to the frame/bounds/position of CALayer. The center and position are the locations of anchorPoint corresponding to the parent layer. The frame/bounds/center of UIView is only an access method, these attributes of the UIView are actually the attributes corresponding to CALayer. the frame attribute of CALayer is a computing attribute. It is calculated based on the bounds/position/transform attributes. Changing the frame value may also affect the value, if the frame and bounds are no longer consistent after rotation and scaling, the bounds is the width and height, and the frame also calculates the space occupied by the x and Y axes after rotation, such

CALayer uses anchorPoint (anchorPoint) and center (position) pairs to control the position of the UIView. The anchorPoint is a position relative to the UIView, and the center is a point, because the anchorPoint attribute is blocked for UIView, and the default anchorPoint value is {0.5, 0.5}, this attribute is called center. UIView and CALayertransform rotate around this anchorPoint. In this case, if it is a circular motion (such as clock rotation), you need to set the value of the anchorPoint to make it rotate normally. for example

Both CALayer and UIView have a set of coordinates that can convert its position relative to the current parent layer to the position relative to other layers (or views). The Mac OS and iOS coordinate systems are opposite, iOS. the zPosition attribute of layer is used to set its vertical axis position. The default value is 0. Therefore, if you set it to 1, it will be displayed on other layers.

You can determine whether the clicked point is on a layer or view through Relative Coordinate conversion. The Code is as follows:

 1 var point = (touches as NSSet).anyObject()?.locationInView(self.view) 2 point = blueLayer.convertPoint(point!, fromLayer: self.view.layer) 3  4 if blueLayer.containsPoint(point!) { 5     println("touch in blue") 6      7     let yellowPoint = yellowLayer.convertPoint(point!, fromLayer: blueLayer) 8     if yellowLayer.containsPoint(yellowPoint) { 9         println("touch in yellow")10     }11     12     let redPoint = redLayer.convertPoint(point!, fromLayer: blueLayer)13     if redLayer.containsPoint(redPoint) {14         println("touch in red")15     }16 }

 

HitTest can get the layer you touch:

let point = (touches as NSSet).anyObject()?.locationInView(self.view)let layer = self.view.layer.hitTest(point!)if layer == blueLayer {    println("touch in blue")}if layer == yellowLayer {    println("touch in yellow")}if layer == redLayer {    println("touch in red")}

UIView can achieve adaptive screen rotation through attributes such as autoresizingMask and constraints. CaLayer also has the corresponding layoutManager attributes and CAConstraintLayoutManager class, but can only be used on Mac OS, which is not supported on iOS, if you want to use this feature, you cannot use the layer independently, but if you want to adjust the layer size, you can still set the layer's delegate, and then implement the proxy method layoutSublayersOfLayer to directly modify the size and color, it also needs to call the setNeedsLayout method, which is the same as the layoutSubviews corresponding to the UIView.

Visual Effects
Rounded corner
The cornerRadius attribute of layer allows you to set the curvature of the rounded corner. If the curvature is half the length of the side, the rounded corner is cut inside the side. If it is a square, the last result is a circle, if you want to crop the child view, you can also crop the child view directly in the circle.

Border
The borderColor of layer sets the border color, which is CGColorRef and borderWidth sets the Border width. It is worth noting that the Border Width occupies the width of the frame of the layer, it does not add a border to the layer but is generated internally. the layer will be covered by the quilt layer, but the border will not be covered, and the border is only used for display, it will not interfere with touch and events, there are no borders are the same.

Shadow
ShadowColor, shadowOffset, and shadowOpacity must be at least three attributes for the shadowColor to take effect. The value of shadowOffset is of the CGSize type, and the two positive values are in the lower right corner. another attribute, shadowRadius, controls the Blur degree of the Shadow boundary. The default value is 3. If the value is 0, it is not blurred. The greater the value, the blurrier the result, the CGSize is assured that the color is heavy, the shadow in other directions also has a sense of attention.
Because the shadow is outside the layer, if you want to crop a child view that exceeds the layer, you need to use the maskToBounds attribute. In this case, the shadow is also cropped, therefore, when maskToBounds and shadow coexist, special processing is required:

 1 blueLayer = CALayer() 2 blueLayer.frame = CGRectMake(50, 100, 300, 300) 3 blueLayer.backgroundColor = UIColor.blueColor().CGColor 4 blueLayer.cornerRadius = blueLayer.bounds.size.width / 2.0 5 blueLayer.borderColor = UIColor.purpleColor().CGColor 6 blueLayer.borderWidth = 10.0 7  8 blueLayer.masksToBounds = true 9 10 let shadowLayer = CALayer()11 shadowLayer.frame = blueLayer.frame12 shadowLayer.cornerRadius = blueLayer.cornerRadius13 shadowLayer.shadowColor = UIColor.redColor().CGColor14 shadowLayer.shadowOffset = CGSizeMake(23 , 23.0)15 shadowLayer.shadowOpacity = 116 shadowLayer.shadowRadius = 6017 shadowLayer.backgroundColor = UIColor.redColor().CGColor18 self.view.layer.addSublayer(shadowLayer)19 20 self.view.layer.addSublayer(blueLayer)

Note that the shadow layer must have a background color. Otherwise, its shadow cannot be displayed.

The shadowPath attribute can be used to set the shadow shape. Note that CGMutablePath in swift does not increase the reference count. You do not need relase, and there is no way to provide release to you.

1  let  circlePath = CGPathCreateMutable()2  CGPathAddEllipseInRect(circlePath, nil, self.blueLayer.bounds)3  shadowLayer.shadowPath = circlePath

You can also use UIBezierPath to set more complex shapes for shadowPath.

1 let path1 = UIBezierPath(roundedRect: CGRectMake(-75, -75, 200, 200), cornerRadius: 30).CGPath2 let path2 = UIBezierPath(arcCenter: CGPointMake(25, 40), radius: 100, startAngle: 0, endAngle: 3.14159265, clockwise: true).CGPath3 shadowLayer.shadowPath = path14 shadowLayer.shadowPath = path2

Picture mask

You can set a layer for the layer's mask attribute. The contents of this layer should be a 32-bit png Image with alpha channel. You can set an irregular picture to transparent in other parts, in this way, a mask is set for the layer, the color of the mask is not important, the outline is more important, and the layer with the mask is finally set to only display the content of the mask shape.

1 let maskLayer = CALayer()2 maskLayer.frame = CGRectMake(0, 0, 100, 100)3 maskLayer.contents = UIImage(named: "111.png")?.CGImage4 blueLayer.mask = maskLayer

 

Stretch

There are many advantages if you do not need to stretch the image, that is, you do not need to stretch the image, but you can use the memory and cpu reasonably. However, in many cases, one image needs to be used in multiple locations, so we need to stretch. iOS and we provide a 3 medium stretch mode.KCAFilterLinear/kCAFilterNearest/kCAFilterTrilinear. To set the stretch mode, you only need to assign the corresponding stretch mode to the two attributes of the layer: minification (image reduction) and magniication (image amplification ), this attribute is kCAFilterLinear by default. It is similar to kCAFilterTrilinear. They are all linear, meaning that it will take the excessive colors of two values to make the corresponding point smooth and smooth, if the image has more gradient and diagonal lines, you need to use this default value. If the image is mainly monochrome and mainly vertical, you need kCAFilterNearest, it is violent and takes the surrounding color directly, so it will not be distorted, and it will not consume too much cpu

Group Transparency

IOS8 is a set of transparency by default. Before applying transparency, it will integrate the child layer with it into a whole picture, so there is no problem of transparency mixing, currently, no transparency issues have been tested. You can set the shouldRasterize value of the layer to YES.

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.