Swift 解决圆角性能问题

作者: 屈涯 | 来源:发表于2020-03-25 14:23 被阅读0次

如果使用正常圆角, 在少量圆角时候不会有问题, 但大量圆角时候,因为离屏渲染, 就会有卡顿,这时候我们就需要这套代码了。

import Foundation
import UIKit

public class SKArchCutter_Swift: NSObject {
    
    /** 切割UIView、UIButton和UILabel圆角
     * @param view 需要进行切割的对象
     * @param direction 切割的方向
     * @param cornerRadii 圆角半径
     * @param borderWidth 边框宽度
     * @param borderColor 边框颜色
     * @param backgroundColor 背景色
     */
    public class func cuttingView(view: UIView, direction: UIRectCorner, cornerRadii: CGFloat, borderWidth: CGFloat, borderColor: UIColor, backgroundColor: UIColor)
    {
        var cornerRadii = cornerRadii
        if view.bounds.size.height != 0 && view.bounds.size.width != 0 {// 使用Masonry布局后,view的bounds是异步返回的,这里需要做初步的判断
            let width = view.bounds.size.width
            let height = view.bounds.size.height
            
            // 先利用CoreGraphics绘制一个圆角矩形
            UIGraphicsBeginImageContextWithOptions(view.bounds.size, false, UIScreen.main.scale)
            let currentContext = UIGraphicsGetCurrentContext()
            
            if (currentContext != nil) {
                currentContext?.setFillColor(backgroundColor.cgColor)// 设置填充颜色
                currentContext?.setStrokeColor(borderColor.cgColor)// 设置画笔颜色
                
                if cornerRadii == 0 {
                    cornerRadii = view.bounds.size.height / 2
                }
                // 单切圆角
                if direction == UIRectCorner.allCorners {
                    currentContext?.move(to: CGPoint.init(x: width - borderWidth, y: cornerRadii + borderWidth))// 从右下开始
                    currentContext?.addArc(tangent1End: CGPoint.init(x: width - borderWidth, y: height - borderWidth), tangent2End: CGPoint.init(x: width - cornerRadii - borderWidth, y: height - borderWidth), radius: cornerRadii)
                    currentContext?.addArc(tangent1End: CGPoint.init(x: borderWidth, y: height - borderWidth), tangent2End: CGPoint.init(x: borderWidth, y: height - cornerRadii - borderWidth), radius: cornerRadii)
                    currentContext?.addArc(tangent1End: CGPoint.init(x: borderWidth, y: borderWidth), tangent2End: CGPoint.init(x: width - borderWidth, y: borderWidth), radius: cornerRadii)
                    currentContext?.addArc(tangent1End: CGPoint.init(x: width - borderWidth, y: borderWidth), tangent2End: CGPoint.init(x: width - borderWidth, y:  cornerRadii + borderWidth), radius: cornerRadii)
                    
                } else {
                    currentContext?.move(to: CGPoint.init(x: cornerRadii + borderWidth, y: borderWidth))// 从左上开始
                    if direction.contains(UIRectCorner.topLeft) {
                        currentContext?.addArc(tangent1End: CGPoint.init(x: borderWidth, y: borderWidth), tangent2End: CGPoint.init(x: borderWidth, y: cornerRadii + borderWidth), radius: cornerRadii)
                    } else {
                        currentContext?.addLine(to: CGPoint.init(x: borderWidth, y: borderWidth))
                    }
                    if direction.contains(UIRectCorner.bottomLeft) {
                        currentContext?.addArc(tangent1End: CGPoint.init(x: borderWidth, y: height - borderWidth), tangent2End: CGPoint.init(x: borderWidth + cornerRadii, y: height - borderWidth), radius: cornerRadii)
                    } else {
                        currentContext?.addLine(to: CGPoint.init(x: borderWidth, y: height - borderWidth))
                    }
                    if direction.contains(UIRectCorner.bottomRight) {
                        currentContext?.addArc(tangent1End: CGPoint.init(x: width - borderWidth, y: height - borderWidth), tangent2End: CGPoint.init(x: width - borderWidth, y: height - borderWidth - cornerRadii), radius: cornerRadii)
                    } else {
                        currentContext?.addLine(to: CGPoint.init(x: width - borderWidth, y: height - borderWidth))
                    }
                    if direction.contains(UIRectCorner.topRight) {
                        currentContext?.addArc(tangent1End: CGPoint.init(x: width - borderWidth, y: borderWidth), tangent2End: CGPoint.init(x: width - borderWidth - cornerRadii, y: borderWidth), radius: cornerRadii)
                    } else {
                        currentContext?.addLine(to: CGPoint.init(x: width - borderWidth, y: borderWidth))
                    }
                    currentContext?.addLine(to: CGPoint.init(x: borderWidth + cornerRadii, y: borderWidth))
                    
                }
                currentContext?.drawPath(using: .fillStroke)
                let image = UIGraphicsGetImageFromCurrentImageContext()
                UIGraphicsEndImageContext()
                
                // 绘制完成后,将UIImageView插入到view视图层级的底部
                if (image?.isKind(of: UIImage.self))! {
                    let baseImageView = UIImageView.init(image: image)
                    view.insertSubview(baseImageView, at: 0)
                }
            }
        } else {// 如果没有获取到view的bounds时
            DispatchQueue.main.async {
                self.cuttingView(view: view, direction: direction, cornerRadii: cornerRadii, borderWidth: borderWidth, borderColor: borderColor, backgroundColor: backgroundColor)
            }
        }
    }
    
    /** 切割UIImageView圆角
     * @param imageView 需要进行切割的对象
     * @param direction 切割的方向
     * @param cornerRadii 圆角半径
     * @param borderWidth 边框宽度
     * @param borderColor 边框颜色
     * @param backgroundColor 背景色
     */
    public class func cuttingImageView(imageView: UIImageView, direction: UIRectCorner, cornerRadii: CGFloat, borderWidth: CGFloat, borderColor: UIColor, backgroundColor: UIColor)
    {
        var cornerRadii = cornerRadii
        if imageView.bounds.size.height != 0 && imageView.bounds.size.width != 0 {
            // 先截取UIImageView视图Layer生成的Image,然后再做渲染
            var image : UIImage? = nil
            if (imageView.image != nil) {
                image = imageView.image
            } else {
                DispatchQueue.main.async {
                    self.cuttingImageView(imageView: imageView, direction: direction, cornerRadii: cornerRadii, borderWidth: borderWidth, borderColor: borderColor, backgroundColor: backgroundColor)
                }
            }

            if cornerRadii == 0 {
                cornerRadii = imageView.bounds.size.height / 2
            }
            let rect = CGRect.init(origin: CGPoint.init(x: 0, y: 0), size: CGSize.init(width: imageView.bounds.size.width, height: imageView.bounds.size.height))
            UIGraphicsBeginImageContextWithOptions(rect.size, false, UIScreen.main.scale)
            let currentContext = UIGraphicsGetCurrentContext()
            if (currentContext != nil) {
                let path = UIBezierPath.init(roundedRect: rect, byRoundingCorners: direction, cornerRadii: CGSize.init(width: cornerRadii - borderWidth, height: cornerRadii - borderWidth))
                currentContext?.addPath(path.cgPath)
                currentContext?.clip()
                
                image?.draw(in: rect)
                borderColor.setStroke()// 画笔颜色
                backgroundColor.setFill()// 填充颜色
                path.stroke()
                path.fill()
                image = UIGraphicsGetImageFromCurrentImageContext()
                UIGraphicsEndImageContext()
            }
            if (image?.isKind(of: UIImage.self))! {
                imageView.image = image
            } else {// UITableViewCell的UIImageView,第一次创建赋图时,可能无法获取UIImageView视图layer的图片
                DispatchQueue.main.async {
                    self.cuttingImageView(imageView: imageView, direction: direction, cornerRadii: cornerRadii, borderWidth: borderWidth, borderColor: borderColor, backgroundColor: backgroundColor)
                }
            }
        } else {
            DispatchQueue.main.async {
                self.cuttingImageView(imageView: imageView, direction: direction, cornerRadii: cornerRadii, borderWidth: borderWidth, borderColor: borderColor, backgroundColor: backgroundColor)
            }

        }
        
    }

}

相关文章

  • Swift 解决圆角性能问题

    如果使用正常圆角, 在少量圆角时候不会有问题, 但大量圆角时候,因为离屏渲染, 就会有卡顿,这时候我们就需要这套代码了。

  • 圆角阴影

    全圆角阴影 部分圆角阴影 swift 版

  • 如何优雅的为UIView添加圆角?

    一.在解决UIView的圆角问题之前,我们先看一下UITableView的卡顿问题。 1.在解决关于添加圆角的问题...

  • iOS图片圆角优化(一)

    关于图片圆角的,用到了大量圆角图片。然而,系统圆角会导致离屏渲染的问题,出于性能考虑,于是有了图片圆角渲染工具HJ...

  • iOS 圆角性能问题

    http://www.jianshu.com/p/fa509c423db1?utm_campaign=malesk...

  • iOS 圆角性能问题

    偶然的一下,看到了圆角设置性能的一些问题,自己以前使用的话就没有怎么想过这个问题,现在自己也研究了一下,也希望和大...

  • iOS开发收集的小技巧

    解决从Assets读取的照片做透明圆角处理后,写入相册时圆角区域变白问题 /// 问题:将读取的照片做透明圆角处理...

  • iOS Swift 圆角阴影效果参考代码

    iOS Swift 圆角阴影效果

  • 用Swift的函数式编程解决硬币问题

    用Swift的函数式编程解决硬币问题 用Swift的函数式编程解决硬币问题

  • flutter技巧

    showModalBottomSheet 无法直接设置圆角;使用stack包裹住子组件解决圆角的问题,且需要设置背...

网友评论

    本文标题:Swift 解决圆角性能问题

    本文链接:https://www.haomeiwen.com/subject/rontuhtx.html