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:彩虹色圈的主要内容,如果未能解决你的问题,请参考以下文章