#10 調色大師_悟天克斯

Adam
彼得潘的 Swift iOS / Flutter App 開發教室
21 min readAug 8, 2024

作業目的: 熟練 outlet,action,UISlider,UIColor。

目標功能:

  1. 用Segmented Control選擇要調整頭髮、褲子、光環,三個地方的顏色和透明度。
  2. 滑動Slider改變顏色、透明度、圓角和邊框寬度。
  3. 用Switch控制圓角和邊框寬度是否能調整。

先找好要用的圖片並去背,看其他學長姐文章時發現去背的圖片可以在PNGEGG這裡找,很方便!

hair & pants & aura

因為要修改這三張圖片的顏色,所以新增3個view來對應,並在viewDidLoad裡用程式改成可以著色。

@IBOutlet weak var auraView: UIView!
@IBOutlet weak var hairView: UIView!
@IBOutlet weak var pantsView: UIView!

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
var image = UIImage(named: "aura")
let auraImageView = UIImageView(image: image)
auraImageView.frame = auraView.bounds
auraImageView.contentMode = .scaleAspectFill
auraView.mask = auraImageView
auraView.backgroundColor = UIColor(red: 0.5, green: 0.5, blue: 0.5, alpha: 0.5)

image = UIImage(named: "hair")
let hairImageView = UIImageView(image: image)
hairImageView.frame = hairView.bounds
hairImageView.contentMode = .scaleAspectFill
hairView.mask = hairImageView
hairView.backgroundColor = UIColor(red: 0.5, green: 0.5, blue: 0.5, alpha: 0.5)

image = UIImage(named: "pants")
let pantsImageView = UIImageView(image: image)
pantsImageView.frame = pantsView.bounds
pantsImageView.contentMode = .scaleAspectFill
pantsView.mask = pantsImageView
pantsView.backgroundColor = UIColor(red: 0.5, green: 0.5, blue: 0.5, alpha: 0.5)

}

圖片完成後,就把要用的UI元件擺上去~

更改Slider上面滑動圓點的圖片

總共有6個Slider,我要把每個Slider的圓點改成一顆龍珠圖案,因為都是相同的元件,在拉線outlet時可以直接用outlet collection存進array裡,在用迴圈改圖案,而且畫面上變數也會比較少。(龍珠圖案40*40pixels)

@IBOutlet var sliderValues: [UISlider]!

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.

//迴圈改Slider圖案
for slider in sliderValues {
slider.setThumbImage(UIImage(named: "dragonball"), for: .normal)
}

}

設置圓角和邊框的Switch開關

開關預設是先關閉,要打開才會出現Slider可以調整,如果關閉調整的效果會消失,打開才會恢復,然後因為圖片是很多view重疊再一起,所以修改圓角和邊框時要把會影響到的view都要一起修改,效果才會同步,我的圖片就要同時改3個view。

    //圓角開關
@IBAction func cornerRadiusSwitch(_ sender: UISwitch) {
if sender.isOn{
sliderValues[4].isHidden = false
auraView.layer.cornerRadius = CGFloat(sliderValues[4].value)
gotenksImageView.layer.cornerRadius = CGFloat(sliderValues[4].value)
backgroundImageView.layer.cornerRadius = CGFloat(sliderValues[4].value)
}else{
sliderValues[4].isHidden = true
auraView.layer.cornerRadius = 10
gotenksImageView.layer.cornerRadius = 10
backgroundImageView.layer.cornerRadius = 10
}
}

//邊框開關
@IBAction func borderWidthSwitch(_ sender: UISwitch) {
if sender.isOn{
sliderValues[5].isHidden = false
auraView.layer.borderWidth = CGFloat(sliderValues[5].value)
gotenksImageView.layer.borderWidth = CGFloat(sliderValues[5].value)
backgroundImageView.layer.borderWidth = CGFloat(sliderValues[5].value)
}else{
sliderValues[5].isHidden = true
auraView.layer.borderWidth = 1
gotenksImageView.layer.borderWidth = 1
backgroundImageView.layer.borderWidth = 1
}
}

Code:

import UIKit

class ViewController: UIViewController {

@IBOutlet weak var backgroundImageView: UIImageView!
@IBOutlet weak var gotenksImageView: UIImageView!
@IBOutlet weak var auraView: UIView!
@IBOutlet weak var hairView: UIView!
@IBOutlet weak var pantsView: UIView!
@IBOutlet var sliderValues: [UISlider]!
@IBOutlet var showValues: [UILabel]!
@IBOutlet weak var partSegmentedControl: UISegmentedControl!

var hairSliderValue : [Float] = [0.5,0.5,0.5,0.5]
var pantsSliderValue : [Float] = [0.5,0.5,0.5,0.5]
var auraSliderValue : [Float] = [0.5,0.5,0.5,0.5]

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
var image = UIImage(named: "aura")
let auraImageView = UIImageView(image: image)
auraImageView.frame = auraView.bounds
auraImageView.contentMode = .scaleAspectFill
auraView.mask = auraImageView
auraView.backgroundColor = UIColor(red: 0.5, green: 0.5, blue: 0.5, alpha: 0.5)

image = UIImage(named: "hair")
let hairImageView = UIImageView(image: image)
hairImageView.frame = hairView.bounds
hairImageView.contentMode = .scaleAspectFill
hairView.mask = hairImageView
hairView.backgroundColor = UIColor(red: 0.5, green: 0.5, blue: 0.5, alpha: 0.5)

image = UIImage(named: "pants")
let pantsImageView = UIImageView(image: image)
pantsImageView.frame = pantsView.bounds
pantsImageView.contentMode = .scaleAspectFill
pantsView.mask = pantsImageView
pantsView.backgroundColor = UIColor(red: 0.5, green: 0.5, blue: 0.5, alpha: 0.5)

for slider in sliderValues {
slider.setThumbImage(UIImage(named: "dragonball"), for: .normal)
}

auraView.layer.cornerRadius = 10
auraView.clipsToBounds = true
auraView.layer.borderWidth = 1
auraView.layer.borderColor = CGColor(red: 0, green: 0, blue: 0, alpha: 1)

gotenksImageView.layer.cornerRadius = 10
gotenksImageView.clipsToBounds = true
gotenksImageView.layer.borderWidth = 1
gotenksImageView.layer.borderColor = CGColor(red: 0, green: 0, blue: 0, alpha: 1)

backgroundImageView.layer.cornerRadius = 10
backgroundImageView.clipsToBounds = true
backgroundImageView.layer.borderWidth = 1
backgroundImageView.layer.borderColor = CGColor(red: 0, green: 0, blue: 0, alpha: 1)

sliderValues[4].isHidden = true
sliderValues[5].isHidden = true

}

//調整RGB,Alpha的Slider
@IBAction func changeColor(_ sender: Any) {
changeViewColor()
colorValueSave()
colorValueShow()
}

//切換SegmentedControl
@IBAction func changePart(_ sender: UISegmentedControl) {
colorValueSet()
colorValueShow()
}

//調整圓角大小
@IBAction func changeCornerRadius(_ sender: Any) {
auraView.layer.cornerRadius = CGFloat(sliderValues[4].value)
gotenksImageView.layer.cornerRadius = CGFloat(sliderValues[4].value)
backgroundImageView.layer.cornerRadius = CGFloat(sliderValues[4].value)
}

//調整邊框寬度
@IBAction func changeBorderWidth(_ sender: Any) {
auraView.layer.borderWidth = CGFloat(sliderValues[5].value)
gotenksImageView.layer.borderWidth = CGFloat(sliderValues[5].value)
backgroundImageView.layer.borderWidth = CGFloat(sliderValues[5].value)
}

//圓角開關
@IBAction func cornerRadiusSwitch(_ sender: UISwitch) {
if sender.isOn{
sliderValues[4].isHidden = false
auraView.layer.cornerRadius = CGFloat(sliderValues[4].value)
gotenksImageView.layer.cornerRadius = CGFloat(sliderValues[4].value)
backgroundImageView.layer.cornerRadius = CGFloat(sliderValues[4].value)
}else{
sliderValues[4].isHidden = true
auraView.layer.cornerRadius = 10
gotenksImageView.layer.cornerRadius = 10
backgroundImageView.layer.cornerRadius = 10
}
}

//邊框開關
@IBAction func borderWidthSwitch(_ sender: UISwitch) {
if sender.isOn{
sliderValues[5].isHidden = false
auraView.layer.borderWidth = CGFloat(sliderValues[5].value)
gotenksImageView.layer.borderWidth = CGFloat(sliderValues[5].value)
backgroundImageView.layer.borderWidth = CGFloat(sliderValues[5].value)
}else{
sliderValues[5].isHidden = true
auraView.layer.borderWidth = 1
gotenksImageView.layer.borderWidth = 1
backgroundImageView.layer.borderWidth = 1
}
}

//Random按鈕
@IBAction func randomColor(_ sender: Any) {
sliderValues[0].value = Float.random(in: 0...1)
sliderValues[1].value = Float.random(in: 0...1)
sliderValues[2].value = Float.random(in: 0...1)
sliderValues[3].value = Float.random(in: 0...1)

changeViewColor()
colorValueSave()
colorValueShow()
}

//Reset按鈕
@IBAction func resetColor(_ sender: Any) {
sliderValues[0].value = 0.5
sliderValues[1].value = 0.5
sliderValues[2].value = 0.5
sliderValues[3].value = 0.5

changeViewColor()
colorValueSave()
colorValueShow()
}

//改變View的顏色
func changeViewColor(){
switch partSegmentedControl.selectedSegmentIndex {
case 0 :
hairView.backgroundColor = UIColor(red: CGFloat(sliderValues[0].value), green: CGFloat(sliderValues[1].value) , blue: CGFloat(sliderValues[2].value), alpha: CGFloat(sliderValues[3].value) )
case 1 :
pantsView.backgroundColor = UIColor(red: CGFloat(sliderValues[0].value), green: CGFloat(sliderValues[1].value) , blue: CGFloat(sliderValues[2].value), alpha: CGFloat(sliderValues[3].value) )
case 2 :
auraView.backgroundColor = UIColor(red: CGFloat(sliderValues[0].value), green: CGFloat(sliderValues[1].value) , blue: CGFloat(sliderValues[2].value), alpha: CGFloat(sliderValues[3].value) )
default :
return
}
}

//保存各Slider數值
func colorValueSave(){
switch partSegmentedControl.selectedSegmentIndex {
case 0 :
hairSliderValue[0] = sliderValues[0].value
hairSliderValue[1] = sliderValues[1].value
hairSliderValue[2] = sliderValues[2].value
hairSliderValue[3] = sliderValues[3].value
case 1 :
pantsSliderValue[0] = sliderValues[0].value
pantsSliderValue[1] = sliderValues[1].value
pantsSliderValue[2] = sliderValues[2].value
pantsSliderValue[3] = sliderValues[3].value
case 2 :
auraSliderValue[0] = sliderValues[0].value
auraSliderValue[1] = sliderValues[1].value
auraSliderValue[2] = sliderValues[2].value
auraSliderValue[3] = sliderValues[3].value
default :
return
}
}

//切換SegmentedControl,設置各Slider數值
func colorValueSet(){
switch partSegmentedControl.selectedSegmentIndex {
case 0 :
sliderValues[0].setValue(hairSliderValue[0], animated: true)
sliderValues[1].setValue(hairSliderValue[1], animated: true)
sliderValues[2].setValue(hairSliderValue[2], animated: true)
sliderValues[3].setValue(hairSliderValue[3], animated: true)
case 1 :
sliderValues[0].setValue(pantsSliderValue[0], animated: true)
sliderValues[1].setValue(pantsSliderValue[1], animated: true)
sliderValues[2].setValue(pantsSliderValue[2], animated: true)
sliderValues[3].setValue(pantsSliderValue[3], animated: true)
case 2 :
sliderValues[0].setValue(auraSliderValue[0], animated: true)
sliderValues[1].setValue(auraSliderValue[1], animated: true)
sliderValues[2].setValue(auraSliderValue[2], animated: true)
sliderValues[3].setValue(auraSliderValue[3], animated: true)
default :
return
}
}

//顯示RGB數值
func colorValueShow() {
showValues[0].text = String(format: "%.0f", sliderValues[0].value*255)
showValues[1].text = String(format: "%.0f", sliderValues[1].value*255)
showValues[2].text = String(format: "%.0f", sliderValues[2].value*255)
showValues[3].text = String(format: "%.1f", sliderValues[3].value)
}

}

Github:

Reference:

--

--