Swift:彩虹色圈

Posted

技术标签:

【中文标题】Swift:彩虹色圈【英文标题】:Swift: rainbow colour circle 【发布时间】:2017-05-30 12:31:40 【问题描述】:

您好,我正在尝试用 swift 编写颜色选择器,看起来像这样。

但到目前为止,我做到了。

画圆很简单,代码如下……

 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 但它不可见。有什么好的建议吗?

【问题讨论】:

原生不支持圆形渐变。这里有一些不错的选择:***.com/questions/6905466/cgcontextdrawanglegradient 你想参考这个并弄清楚:***.com/questions/11783114/… 感谢您的回复....我将 Dave C 的答案标记为已回答....这正是我想要的。 注意:对于“正确”的像素(或至少是点)解决方案,只需转到此处:***.com/q/47610272/294884 确实,那里有一个链接到(非常旧,但工作)drop-在 github 上上课。 重要! .conic 终于在 12 中可用了,它现在是一行代码。 【参考方案1】:

详情

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)
    

结果

【讨论】:

Спасибо, Василий!) 两种方法可以绘制圆形渐变:您可以 (A) 绘制“很多小线条”,这样可以很好地完成这项工作。或者(B)您可以“简单地”以所需的确切值绘制每个像素。这个答案正确地实现了(A)。如果您想使用 (B),请调查此 QA:***.com/q/47610272/294884 @Vasily Bodnarchuk :但是这个圆圈没有旋转。如何旋转这个? 重要! .conic 终于在 12 中可用了!现在是一行代码。绝对没有必要实施这里解释的遗留解决方案!享受

以上是关于Swift:彩虹色圈的主要内容,如果未能解决你的问题,请参考以下文章

彩虹岛副职业转职流程

华数互联网电视彩虹box认证不成功怎么办

王心凌彩虹的微笑是不是抄袭断背山中的某个插曲?

FC彩虹岛的金手指是啥?

平趟4K剑指8K游戏 七彩虹iGame GeForce RTX 4080 Vulcan首发评测

固态硬盘怎么在七彩虹主板的BISO里面检测有没有坏掉?