How to effectively add rounded corners for iOS and how to add rounded corners for ios

Source: Internet
Author: User

How to effectively add rounded corners for iOS and how to add rounded corners for ios

RounderCorner is a common view effect, which is more gentle and easy to accept than a right angle. However, many people do not know how to set the correct corner. Setting a rounded corner will result in a certain amount of performance loss. How to Improve the Performance is another important topic to be discussed. I have read some existing materials, learned a lot, and found some misleading mistakes. This article summarizes some knowledge points and summarizes them as follows:

  • Set the correct posture of the rounded corner and Its Principle

  • Sets the performance loss of rounded corners.

  • Other methods for setting rounded corners and Optimal Selection

I have created a demo for this article. Readers can clone it on my github: CornerRadius. If you think it is helpful, hope to give a star for support. The project is implemented by Swift, but be sure to understand it even if you only have Objective-C. Because the key knowledge is irrelevant to Swift.

I have created a demo for this article. Readers can clone it on my github: CornerRadius. If you think it is helpful, hope to give a star for support. The project is implemented by Swift, but be sure to understand it even if you only have Objective-C. Because the key knowledge is irrelevant to Swift.

Correct posture

First of all, I want to declare that setting the rounded corner is simple and it will not cause any performance loss.

Because this is simple, it only needs a line of code:

1 view.layer.cornerRadius = 5

Don't rush to turn off the web page, and don't rush to reply. Let's talk about the facts. Open Instuments and select Core Animation for debugging. You will find that neither Off-Screen Render nor reduce the number of frames. For more information about how to use Instuments to analyze applications, see my article: how to optimize the performance of UIKit. The third brown view is indeed rounded:

However, after checking the code, we can see that there is a UILabel with a rounded corner, but it does not show any changes. For this, you can view the comments of the cornerRadius attribute:

By default, the corner radius does not apply to the image in the layer's contents property; it applies only to the background color and border of the layer. however, setting the masksToBounds property to true causes the content to be clipped to the rounded corners.

That is to say, by default, this attribute only affects the background color and border of the view. There is no control for sub-view in UILabel. In many cases, we will see the following code:

12 label.layer.cornerRadius = 5label.layer.masksToBounds = true

We add the second line of code to the constructor of CustomTableViewCell and run Instument again to see the effect of the rounded corner.

Performance Loss

If you select Color Offscreen-Rendered Yellow, a Yellow mark appears around the label, indicating that the off-screen rendering appears. For details about off-screen rendering, refer to: UIKit Performance Tuning practice.

It should be emphasized that off-screen rendering is not caused by setting rounded corners! This conclusion can be easily drawn through the method of controlling variables, because UIView only sets cornerRadius, but it does not show off-screen rendering. Some authoritative articles, such as Stackoverflow and CodeReview, have mentioned that setting cornerRadius will lead to off-screen rendering and thus affect performance. I think this is really embarrassing and misleading.

Although setting masksToBounds will cause off-screen rendering and thus affect performance, how big is the impact? On my iPhone 6, even if there are 17 views with rounded corners, the number of sliding frames still fluctuates around 58-59 fps.

However, this does not indicate that iOS 9 has made any special optimization, or the off-screen rendering has little impact. The main reason is that there are not enough rounded corners. When I set a UIImageView to a rounded corner, that is, when the number of rounded corner views on the screen reaches 34, the fps dropped significantly, about 33. Basically, the impact on user experience has been reached. Therefore, optimization without justification is a rogue. If you have a small number of rounded corner views and the cell is not complex, you don't have to bother yourself.

Efficiently set rounded corners

If there are many rounded corner views (for example, in UICollectionView), how can we efficiently add rounded corners to the view? Most of the tutorials on the Internet are not completely explained, because this issue should be considered in two situations. You can set a rounded corner for a general UIView. The principle for setting a rounded corner for a UIImageView is quite different.

One method is as follows. This method tries to achieve the effect of cornerRadius = 3:

 

 

123456789 override func drawRect(rect: CGRect) {    let maskPath = UIBezierPath(roundedRect: rect,                                byRoundingCorners: .AllCorners,                                cornerRadii: CGSize(width: 3, height: 3))    let maskLayer = CAShapeLayer()    maskLayer.frame = self.bounds    maskLayer.path = maskPath.CGPath    self.layer.mask = maskLayer}

However, this is a wrong way of writing!

First, we should try to avoid rewriting the drawRect method. Improper use of this method will lead to a sharp increase in memory. For example, even if an empty drawRect method is rewritten for large uiviews such as iPhone 6 and the screen, it occupies at least 750*1134*4 bytes ≈ 3.4 Mb of memory. In the drawRect and its follow-up, the author introduced the principle in detail. According to his test, rewriting the drawRect Method on large views over iPhone 6 and on the screen will consume 5.2 Mb of memory. In short, it is possible to avoid rewriting the drawRect method.

Second, this method is essentially implemented using the mask layer mask, so it will inevitably lead to off-screen rendering. I tried to use this method to achieve the rounded corner of the previous 34 views, and the result fps dropped to around 11. It is already a rhythm of the card.

Forget this writing style. The following describes how to set the rounded corner correctly and efficiently.

Add rounded corners for UIView

The principle of this approach is to manually draw a rounded corner. As we have said before, you can directly set the cornerRadius attribute for a common view. However, if you need to use masksToBounds, you can use the following method. Its core code is as follows:

123456789101112131415 func kt_drawRectWithRoundedCorner(radius radius: CGFloat,                              borderWidth: CGFloat,                                  backgroundColor: UIColor,                                  borderColor: UIColor) -> UIImage {         UIGraphicsBeginImageContextWithOptions(sizeToFit, false, UIScreen.mainScreen().scale)     let context = UIGraphicsGetCurrentContext()          CGContextMoveToPoint (context, start position );// Start at the right of the Start Coordinate     CGContextAddArcToPoint(context, x1, y1, x2, y2, radius);  // This type of code is repeated four times        CGContextDrawPath(UIGraphicsGetCurrentContext(), .FillStroke)       let output = UIGraphicsGetImageFromCurrentImageContext();     UIGraphicsEndImageContext();     return output}

This method returns UIImage, that is, we use Core Graphics to draw a rounded rectangle. Besides some necessary code, CGContextAddArcToPoint function is the core function. The four parameters in the middle of the curve represent the start and end coordinates of the curve, and the last parameter represents the radius. After calling the function four times, you can draw a rounded rectangle. Finally, retrieve the image from the current drawing context and return it.

With this image, we create a UIImageView and insert it to the bottom of the view level:

123456789101112 extension UIView {    func kt_addCorner(radius radius: CGFloat,                      borderWidth: CGFloat,                      backgroundColor: UIColor,                      borderColor: UIColor) {        let imageView = UIImageView(image: kt_drawRectWithRoundedCorner(radius: radius,                                    borderWidth: borderWidth,                                    backgroundColor: backgroundColor,                                    borderColor: borderColor))        self.insertSubview(imageView, atIndex: 0)    }}

The complete code can be found in the project. You only need to write it as follows:

12 let view = UIView(frame: CGRectMake(1,2,3,4))view.kt_addCorner(radius: 6)

Add rounded corners for UIImageView

Compared with the preceding implementation method, adding rounded corners for UIImageView is more common. Its implementation idea is to directly intercept images:

123456789101112131415161718 extension UIImage {    func kt_drawRectWithRoundedCorner(radius radius: CGFloat, _ sizetoFit: CGSize) -> UIImage {        let rect = CGRect(origin: CGPoint(x: 0, y: 0), size: sizetoFit)                 UIGraphicsBeginImageContextWithOptions(rect.size, false, UIScreen.mainScreen().scale)        CGContextAddPath(UIGraphicsGetCurrentContext(),            UIBezierPath(roundedRect: rect, byRoundingCorners: UIRectCorner.AllCorners,                cornerRadii: CGSize(width: radius, height: radius)).CGPath)        CGContextClip(UIGraphicsGetCurrentContext())                 self.drawInRect(rect)        CGContextDrawPath(UIGraphicsGetCurrentContext(), .FillStroke)        let output = UIGraphicsGetImageFromCurrentImageContext();        UIGraphicsEndImageContext();                 return output    }}

The rounded corner path is drawn directly using the besell curve. The unexpected bonus shows which corners can be selected to have the rounded corner effect. This function is used to crop the original UIImage to a rounded corner. With this function, we can expand a method for setting rounded corners for UIImageView:

123456789 extension UIImageView {    /**     /!!! This method is effective only when imageView is not nil     : Param: radius rounded corner radius     */    override func kt_addCorner(radius radius: CGFloat) {        self.image = self.image?.kt_drawRectWithRoundedCorner(radius: radius, self.bounds.size)    }}

The complete code can be found in the project. You only need to write it as follows:

12 let imageView = let imgView1 = UIImageView(image: UIImage(name: ""))imageView.kt_addCorner(radius: 6)

Reminder:

Regardless of the method above, you must use the background color with caution. Because masksToBounds is not set at this time, the Section beyond the rounded corner is still displayed. Therefore, you should not use the background color. You can set the fill color when drawing the rounded rectangle to achieve similar effects.

When adding a rounded corner for UIImageView, make sure that the image attribute is not nil; otherwise, this setting will be invalid.

Practical testing

Return to the demo and test the two methods for setting the rounded corner. First, remove the comments of the two lines of code in the setupContent method:

12 imgView1.kt_addCorner(radius: 5)imgView2.kt_addCorner(radius: 5)

Then, use the custom method to set the rounded corner for the label and view:

12 view.kt_addCorner(radius: 6)label.kt_addCorner(radius: 6)

Now, we have not only successfully added the rounded corner effect, but also ensured that the performance is not affected:

Performance Testing

Summary

  • If you can solve the problem with only cornerRadius, you do not need to optimize it.

  • If you must set masksToBounds, you can refer to the number of rounded corner views. If the number is small (only a few entries per page), you can also consider not to optimize it.

  • The rounded corner of UIImageView is achieved by directly capturing the image. The rounded corner of other views can be drawn using the Core Graphics.

  • Q: one-click call to programmer Q & A artifacts, one-to-one service, developer programming required official website: www.wenaaa.com

    QQ Group 290551701 has gathered many Internet elites, Technical Directors, architects, and project managers! Open-source technology research, welcome to the industry, Daniel and beginners interested in IT industry personnel!

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.