Swift 4中如何让自定义绘图应用滑块调整的UIColor色相?
嘿,这事儿不难搞定!你已经搭好了自定义CircleView的基础框架,只需要把滑块的色相调整和CircleView的颜色属性绑定起来就行,我给你一步步拆解:
1. 完善CircleView的绘制逻辑
你的CircleView已经有了color属性的观察者(didSet),这部分是对的——颜色变化时自动触发重绘。只是代码里有两处小问题需要修正:
UIColor().white可以简化成UIColor.white,不需要额外的初始化调用draw(_:)方法里漏了context.fillPath(),这是填充颜色的关键步骤
修正后的CircleView代码:
class CircleView: UIView { // 初始化默认白色,颜色变化时自动触发重绘 var color: UIColor = .white { didSet { setNeedsDisplay() } } override func draw(_ rect: CGRect) { guard let context = UIGraphicsGetCurrentContext() else { return } // 绘制圆形路径 let center = CGPoint(x: bounds.midX, y: bounds.midY) let radius = bounds.height / 2 context.addArc(center: center, radius: radius, startAngle: 0, endAngle: 2 * .pi, clockwise: true) // 填充颜色 color.setFill() context.fillPath() } }
2. 绑定滑块与CircleView的色相调整
接下来在ViewController里处理滑块的逻辑,UIColor的色相(hue)参数范围是0~1,所以我们把滑块的取值范围也设为0~1,拖动滑块时实时计算新的颜色并赋值给CircleView。
示例ViewController代码:
class ViewController: UIViewController { // 自定义圆形视图和色相滑块 let circleView = CircleView() let hueSlider = UISlider() override func viewDidLoad() { super.viewDidLoad() setupUI() setupSliderAction() } // 布局视图 private func setupUI() { // 添加CircleView到页面并居中 circleView.translatesAutoresizingMaskIntoConstraints = false view.addSubview(circleView) NSLayoutConstraint.activate([ circleView.centerXAnchor.constraint(equalTo: view.centerXAnchor), circleView.centerYAnchor.constraint(equalTo: view.centerYAnchor), circleView.widthAnchor.constraint(equalToConstant: 100), circleView.heightAnchor.constraint(equalToConstant: 100) ]) // 添加滑块到页面底部 hueSlider.translatesAutoresizingMaskIntoConstraints = false view.addSubview(hueSlider) NSLayoutConstraint.activate([ hueSlider.centerXAnchor.constraint(equalTo: view.centerXAnchor), hueSlider.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -20), hueSlider.widthAnchor.constraint(equalToConstant: 300) ]) } // 设置滑块的取值范围与事件监听 private func setupSliderAction() { hueSlider.minimumValue = 0 hueSlider.maximumValue = 1 hueSlider.value = 0 // 初始色相为红色 // 滑块值变化时触发颜色更新 hueSlider.addTarget(self, action: #selector(updateCircleColor(_:)), for: .valueChanged) } // 根据滑块值更新CircleView的颜色 @objc private func updateCircleColor(_ sender: UISlider) { // 基于滑块值生成新的色相颜色,保持饱和度、亮度为1,完全不透明 let newColor = UIColor(hue: CGFloat(sender.value), saturation: 1, brightness: 1, alpha: 1) // 赋值后自动触发CircleView的重绘 circleView.color = newColor } }
进阶:基于原有颜色调整色相
如果不想固定饱和度和亮度,而是基于CircleView当前的颜色只调整色相,可以用下面的方式计算新颜色:
@objc private func updateCircleColor(_ sender: UISlider) { var currentHue: CGFloat = 0 var saturation: CGFloat = 0 var brightness: CGFloat = 0 var alpha: CGFloat = 0 // 获取当前颜色的HSBA参数 circleView.color.getHue(¤tHue, saturation: &saturation, brightness: &brightness, alpha: &alpha) // 只替换色相值,保留其他参数 let newColor = UIColor(hue: CGFloat(sender.value), saturation: saturation, brightness: brightness, alpha: alpha) circleView.color = newColor }
这样拖动滑块时,CircleView的颜色就会跟着实时变化啦~
内容的提问来源于stack exchange,提问作者WalterBeiter
相关产品推荐
相关产品推荐

