斯威夫特:彩虹色圈 [英] Swift: rainbow colour circle

查看:101
本文介绍了斯威夫特:彩虹色圈的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试像这样快速编写颜色选择器.

Hi i am trying to write colour picker in swift that looks like this.

但是到目前为止,我已经做到了.

But so far I managed this.

绘制圆圈很简单,这是代码...

Draw circle was easy, heres code...

 fileprivate func setupScene(){

    let circlePath: UIBezierPath = UIBezierPath(arcCenter: CGPoint(x: self.wheelView.frame.width/2, y: self.wheelView.frame.height/2), radius: CGFloat(self.wheelView.frame.height/2), startAngle: CGFloat(0), endAngle:CGFloat(Double.pi * 2), clockwise: true)

    let shapeLayer = CAShapeLayer()
    shapeLayer.path = circlePath.cgPath

    //color inside circle
    shapeLayer.fillColor = UIColor.clear.cgColor
    //colored border of circle
    shapeLayer.strokeColor = UIColor.purple.cgColor
    //width size of border
    shapeLayer.lineWidth = 10

    wheelView.layer.addSublayer(shapeLayer)
}

@IBOutlet var wheelView: UIView!

但是现在我不知道如何插入彩虹色了……我尝试了CAGradientLayer,但是它不可见.有什么好的建议吗?

But now I don't know how to insert rainbow colours ... I tried CAGradientLayer but it was not visible. Any good advice?

推荐答案

详细信息

  • Xcode 9.1,快速4
  • Xcode 10.2.1(10E1001),Swift 5
  • 代码取自 https://github.com/joncardasis/ChromaColorPicker

    import UIKit
    
    class RainbowCircle: UIView {
    
        private var radius: CGFloat {
            return frame.width>frame.height ? frame.height/2 : frame.width/2
        }
    
        private var stroke: CGFloat = 10
        private var padding: CGFloat = 5
    
        //MARK: - Drawing
        override func draw(_ rect: CGRect) {
            super.draw(rect)
            drawRainbowCircle(outerRadius: radius - padding, innerRadius: radius - stroke - padding, resolution: 1)
        }
    
        init(frame: CGRect, lineHeight: CGFloat) {
            super.init(frame: frame)
            stroke = lineHeight
        }
    
        required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) }
    
        /*
         Resolution should be between 0.1 and 1
         */
        private func drawRainbowCircle(outerRadius: CGFloat, innerRadius: CGFloat, resolution: Float) {
            guard let context = UIGraphicsGetCurrentContext() else { return }
            context.saveGState()
            context.translateBy(x: self.bounds.midX, y: self.bounds.midY) //Move context to center
    
            let subdivisions:CGFloat = CGFloat(resolution * 512) //Max subdivisions of 512
    
            let innerHeight = (CGFloat.pi*innerRadius)/subdivisions //height of the inner wall for each segment
            let outterHeight = (CGFloat.pi*outerRadius)/subdivisions
    
            let segment = UIBezierPath()
            segment.move(to: CGPoint(x: innerRadius, y: -innerHeight/2))
            segment.addLine(to: CGPoint(x: innerRadius, y: innerHeight/2))
            segment.addLine(to: CGPoint(x: outerRadius, y: outterHeight/2))
            segment.addLine(to: CGPoint(x: outerRadius, y: -outterHeight/2))
            segment.close()
    
            //Draw each segment and rotate around the center
            for i in 0 ..< Int(ceil(subdivisions)) {
                UIColor(hue: CGFloat(i)/subdivisions, saturation: 1, brightness: 1, alpha: 1).set()
                segment.fill()
                //let lineTailSpace = CGFloat.pi*2*outerRadius/subdivisions  //The amount of space between the tails of each segment
                let lineTailSpace = CGFloat.pi*2*outerRadius/subdivisions
                segment.lineWidth = lineTailSpace //allows for seemless scaling
                segment.stroke()
    
                //Rotate to correct location
                let rotate = CGAffineTransform(rotationAngle: -(CGFloat.pi*2/subdivisions)) //rotates each segment
                segment.apply(rotate)
            }
    
            context.translateBy(x: -self.bounds.midX, y: -self.bounds.midY) //Move context back to original position
            context.restoreGState()
        }
    }
    

    用法

    import UIKit
    
    class ViewController: UIViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
            let rainbowCircle = RainbowCircle(frame: CGRect(x: 50, y: 50, width: 240, height: 420), lineHeight: 5)
            rainbowCircle.backgroundColor = .clear
            view.addSubview(rainbowCircle)
        }
    }
    

    结果

    这篇关于斯威夫特:彩虹色圈的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆