Use CALayer to create a star rating component (five-star)

Source: Internet
Author: User

Use CALayer to create a star rating component (five-star)

This document describes how to create the star rating component and how to use CALayer.

To achieve a star rating component, CALayer is used, involving mask, CGPathRef, UIBezierPath, animation, and an algorithm for calculating key nodes of a star.

CALayer manages image-based content and allows us to add animations to the content. UIView and its subclass have an attribute layer. We can use this attribute to make a lot of results. For example, a view with rounded corners, polygon, or even custom shapes, partial occlusion, blur effect erased, partial content shining in turn, and arc progress bar.

First, check a CALayer attribute mask. This attribute is also of the CALayer type. It is used to block content like its name. The default value is nil, so we can see the content on a UIView. If you assign a CALayer instance to the layer attribute of a visible view, the view will immediately disappear. The following code:

CALayer * maskLayer = [CALayer layer];

MaskLayer. frame = testView. bounds;

Self. layer. mask = maskLayer;

Let's look at another kind of CAShapeLayer, which inherits from CALayer and has many additional attributes, such as path, fillColor, and strokeColor. The path attribute determines the content within the range of the "unblocked" path. If we assign the previous mask attribute to a CAShapeLayer instance, or addSublayer the instance on the previous CALayer instance, and specify the path of a center circle, then the common circular Avatar display effect is achieved. The function is the same as setting the corner of the layer of the UIView.

Note that if the fillColor of the added CAShapeLayer is [UIColor clearColor]. CGColor, even in the path range, will also lose the "unblocking" function, and this value is by default non-transparent black. To put it simply, if it is transparent, the content will be blocked. It can be found that the fill and path colors on the mask and Its sublayer are not displayed, and they are only used to determine whether to block the content of their own layer.

Using this feature, we can achieve a similar effect of "Opening the Door" and "closing the door", and add two sublayers on a CALayer as the "door ". You can also achieve more results such as splash ink.

It is worth mentioning that each sublayer can also use the frame and mask attributes to make partial occlusion effect relative to the view.

Return to the fillColor attribute of CAShapeLayer, which fills the path with a certain color. strokeColor specifies the color of the path, and strokeStart and strokeEnd specify the start and end points of the trajectory; there are also line-related attributes that specify the line attributes. Using these attributes, you can make progress bars and animations of any shape.

From the above records, we can see that the path attribute is very important and belongs to the CGPathRef type. The common creation method is CGPathCreateMutable (void) series:

    CGMutablePathRef path = CGPathCreateMutable();    CGPoint firstPoint = [[keyPointsArray firstObject] CGPointValue];    CGPathMoveToPoint(path, nil, firstPoint.x, firstPoint.y);        for (int i = 1; i < keyPointsArray.count; i++) {        CGPoint currentPoint = [keyPointsArray[i] CGPointValue];        CGPathAddLineToPoint(path, nil, currentPoint.x, currentPoint.y);    }        CGPathAddLineToPoint(path, nil, firstPoint.x, firstPoint.y);        _maskLayer.path = path;    _starShapeLayer.path = path;    CGPathRelease(path);

You can also use the series class method of UIBezierPath. After adding the path, the path is obtained by the method-(CGPathRef) CGPath. For example:

    UIBezierPath *bezierPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(_bgShapeLayer.frame.size.width / 2.0, _bgShapeLayer.frame.size.height / 2.0) radius:_radius startAngle:0 endAngle: 2 * M_PI clockwise:YES];    _bgShapeLayer.path = bezierPath.CGPath;

 

Start to record the creation of the star rating component.

For the final effect:

Clicking the left and right sides of a star determines whether to fill in half or all content. You can also set the percentage filling content. Support> 5 stars.

The interior design of a single star is as follows: The view sets the gray background color; view. layer. the mask path is a pentagram; view. layer adds a bgShapeLayer whose background is yellow, controls its width to implement the fill percentage; then adds a starShapeLayer whose path is the same as the pentagram, and sets the path color as the border.

The difficulty here is to calculate the point of intersection of multiple angular stars. If it is a pentagram, the coordinates of 10 key points are required.

The following algorithm records the intersection point:

1. First determine an initial vertex

2. Obtain all external vertices from the positive cosine correlation formula of the trigonometric function based on the Equi-radians and radius.

3. Find the two intersection lines of the inner point

4. Obtain the intersection point from the binary one-time equation.

 

The specific implementation code is as follows:

-(NSArray *) getStarKeyPoints {CGPoint center = CGPointMake (self. frame. size. width/2.0, _ radius); CGFloat sectionAngle = 2 * M_PI/_ topPointCount; NSMutableArray * keyPointsArray = [NSMutableArray array]; CGPoint firstPoint = CGPointMake (center. x, 0); [keyPointsArray addObject: [NSValue valueWithCGPoint: firstPoint]; // peripheral vertex for (int I = 1; I <_ topPointCount; I ++) {CGFloat x = cosf (I * sectionAngle-M_PI_2) * _ radius; CGFloat y = sinf (I * sectionAngle-M_PI_2) * _ radius; CGPoint point = CGPointMake (x + center. x, y + center. y); [keyPointsArray addObject: [NSValue valueWithCGPoint: point];} // NSMutableArray * crossPointsArray = [NSMutableArray array]; // use a binary one-time equation to solve the problem. // The AC points are used to determine the linear equation y = kx + B. // the straight line y = B Over B. y for (int I = 0; I <_ topPointCount; I ++) {CGPoint A = [keyPointsArray [I] CGPointValue]; NSInteger index = I + 1; if (index> _ topPointCount-1) {index-= _ topPointCount;} CGPoint B = [keyPointsArray [index] CGPointValue]; index = I + 2; if (index> _ topPointCount-1) {index-= _ topPointCount;} CGPoint C = [keyPointsArray [index] CGPointValue]; index = I-1; if (index <0) {index + = _ topPointCount;} CGPoint E = [keyPointsArray [index] CGPointValue]; CGFloat F_x = 0.0, F_y = 0.0, k1 = 0.0, k2 = 0.0, b1 = 0.0, b2= 0.0; if (. x = C. x) {F_x =. x;} else {k1 = (. y-C. y)/(. x-C. x); b1 =. y-k1 *. x;} if (B. x = E. x) {F_x = B. x;} else {k2 = (B. y-E. y)/(B. x-E. x); b2 = B. y-k2 * B. x;} if (. x = C. x) {F_y = k2 * F_x + b2;} else if (B. x = E. x) {F_y = k1 * F_x + b1;} else {if (k1 = 0) {F_y =. y; F_x = (F_y-b2)/k2;} else {F_y = (b1 * k2-b2 * k1)/(k2-k1); F_x = (F_y-b1) /k1 ;}} CGPoint pointF = CGPointMake (F_x, F_y); [crossPointsArray addObject: [NSValue valueWithCGPoint: pointF];} // Merge data for (int I = 0; I <crossPointsArray. count; I ++) {[keyPointsArray insertObject: crossPointsArray [I] atIndex :( I * 2 + 1)];} return keyPointsArray ;}

 

Add the key line segment to the path to generate a polygon path for the mask and border layer.

Finally, add a click gesture to determine the operation based on the touch point range.

 

After a single five-pointed star is implemented, five-pointed stars are usually placed side by side to manage the filling percentage of each five-pointed star.

 

ALWStarComment has been updated in the Base project: https://github.com/ALongWay/base.git

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.