[study#8-2] 調色大師-聖誕美甲選色
選了一張手部的圖片,將指甲的部分去背鏤空,剛好適合來調色
除了上色還要加上圖案,所以要準備相應的圖片與圖層安排
UISlider結合UIColor
將去背鏤空圖,連結至程式頁建立outlet,命名為changeView
將顏色及透明度的Slider,連結至程式頁建立outlet,命名為redSlider, greenSlider, blueSlider, alphaSlider
@IBOutlet weak var changeView: UIImageView!@IBOutlet weak var redSlider: UISlider!@IBOutlet weak var greenSlider: UISlider!@IBOutlet weak var blueSlider: UISlider!@IBOutlet weak var alphaSlider: UISlider!
將顏色及透明度的Slider,連結至程式頁建立action
@IBAction func redSliderFunc(_ sender: Any) {
}
@IBAction func greenSliderFunc(_ sender: Any) {
}
@IBAction func blueSliderFunc(_ sender: Any) {
}
@IBAction func alphaSliderFunc(_ sender: Any) {
}
建立redSliderFunc的內容
@IBAction func redSliderFunc(_ sender: Any) { changeView.backgroundColor =
UIColor(displayP3Red: CGFloat(redSlider.value/255),
green: CGFloat(greenSlider.value/255),
blue: CGFloat(blueSlider.value/255),
alpha: CGFloat(alphaSlider.value))}
(由於我想讓顏色的數值呈現不是介在0與1之前, 而是0到255,所以slider的最大值是設為255,func 內容也因應調整)
4個SliderFunc建立相同的內容,在滑動任一Slider時就能改變UIColor
label顯示數值
將代表各數值的Label,連結至程式頁建立outlet,命名為redLabel, greenLabel, blueLabel, alphaLabel
@IBOutlet weak var redLabel: UILabel!@IBOutlet weak var greenLabel: UILabel!@IBOutlet weak var blueLabel: UILabel!@IBOutlet weak var alphaLabel: UILabel!
在各Slider中添加語法,將數值以Label顯示
@IBAction func alphaSliderFunc(_ sender: Any) { ... alphaLabel.text = String(format:"%.2f", alphaSlider.value)}
在alphaSliderFunc內,添加alphaLabel.text語法;
format:”%.2f” 表示格式到小數點第二位
在blueSliderFunc內,添加blueLabel.text語法;
由於希望是整數,所以先添加一個常數 let blueInt = Int(blueSlider.value)
@IBAction func blueSliderFunc(_ sender: Any) { ... let blueInt = Int(blueSlider.value) blueLabel.text = String(blueInt)}
redSliderFunc跟greenSliderFunc用同樣的方式添加。
分區調整顏色
此範例分為左右手可調整不同顏色,最上層的去背鏤空圖至少需分為兩塊(我使用的圖片因位置不易直接切分為左右手,實際切分為3個view)
@IBOutlet weak var rightView: UIImageView!@IBOutlet weak var leftView: UIImageView!
其他操作步驟跟以上一樣,就能為左手與右手分開調色
漸層顯示
比起用Slider顯示漸層,我比較想使用“開關”來顯示漸層
加入Switch開關功能
將Switch連結至程式頁建立action
@IBAction func funcRiGra(_ sender: UISwitch) {
}
在此func中添加if else語法
if sender.isOn {
}
else{
}
isOn表示開啟,此時else表示關閉;
將不同狀態所要顯示的內容放入{}內即可
先前調色是採用backgroundColor,而漸層色是用CAGradientLayer與View
所以我使用多添加一個全透明的imageView
將全透明View連結至程式頁建立outlet,命名rightGraView
@IBOutlet weak var rightGraView: UIImageView!
建立CAGradientLayer
let graRightLayer = CAGradientLayer()graRightLayer.frame = rightGraView.bounds
設定漸層色1: Red: 1, green: 0, blue: 0
設定漸層色2: Red: 0, green: 0.5, blue: 1
graRightLayer.colors = [UIColor.init(displayP3
Red: 1, green: 0, blue: 0, alpha: 1).cgColor, UIColor.init(displayP3
Red: 0, green: 0.5, blue: 1, alpha: 1).cgColor]
將view與漸層遮罩結合
rightGraView.layer.addSublayer(graRightLayer)
設定switch開啟時有漸層,關閉時無漸層;所以將漸層語法放進if
@IBAction func funcRiGra(_ sender: UISwitch) { let graRightLayer = CAGradientLayer() if sender.isOn { graRightLayer.frame = rightGraView.bounds graRightLayer.colors = [UIColor.init(displayP3
Red: 1, green: 0, blue: 0, alpha: 1).cgColor,
UIColor.init(displayP3Red: 0, green: 0.5,
blue: 1, alpha: 1).cgColor] rightGraView.layer.addSublayer(graRightLayer)
} else{ }}
但是這裡事情沒那麼簡單!!
在漸層view之上還有一層有backgroundColor的去背鏤空view
因此需要讓最上層的backgroundColor透明度alpha為0,才能看到漸層view
去背鏤空view的alpha: 0;漸層view的alpha: 1
在關閉switch時,漸層view的alpha設為0,並使去背鏤空view同slider效果
if sender.isOn { changeView.backgroundColor = UIColor(displayP3
Red: 1, green: 1, blue: 1, alpha: 0) rightView.backgroundColor = UIColor(displayP3
Red: 1, green: 1, blue: 1, alpha: 0) leftView.backgroundColor = UIColor(displayP3
Red: 1, green: 1, blue: 1, alpha: 0) graRightLayer.frame = rightGraView.bounds graRightLayer.colors = [UIColor.init(displayP3
Red: 1, green: 0, blue: 0, alpha: 1).cgColor,
UIColor.init(displayP3Red: 0, green: 0.5,
blue: 1, alpha: 1).cgColor] rightGraView.layer.addSublayer(graRightLayer)
}else{ changeView.backgroundColor = UIColor(displayP3Red: CGFloat(redSlider.value/255), green: CGFloat(greenSlider.value/255), blue: CGFloat(blueSlider.value/255), alpha: CGFloat(alphaSlider.value)) rightView.backgroundColor = UIColor(displayP3Red: CGFloat(redSlider.value/255), green: CGFloat(greenSlider.value/255), blue: CGFloat(blueSlider.value/255), alpha: CGFloat(alphaSlider.value)) leftView.backgroundColor = UIColor(displayP3Red: CGFloat(leftRedSlider.value/255), green: CGFloat(leftGreenSlider.value/255), blue: CGFloat(leftBlueSlider.value/255), alpha: CGFloat(leftAlphaSlider.value)) graRightLayer.frame = rightGraView.bounds graRightLayer.colors = [UIColor.init(displayP3
Red: 1, green: 0, blue: 0, alpha: 0).cgColor,
UIColor.init(displayP3Red: 0, green: 0.5,
blue: 1, alpha: 0).cgColor] rightGraView.layer.addSublayer(graRightLayer)}
改變漸層方向
在layer設定startPoint與endPoint,這裡 x 與 y 只能設定1或0
才能顯示需要效果,例如:由右上到左下
graLeftLayer.startPoint = CGPoint(x: 1, y: 0)graLeftLayer.endPoint = CGPoint(x: 0, y: 1)
開啟漸層時,同時可以關閉Slider以避免干擾
開關關閉時,再將slider設定為可使用
@IBAction func funcRiGra(_ sender: UISwitch) { ... if sender.isOn {
alphaSlider.isEnabled = false redSlider.isEnabled = false greenSlider.isEnabled = false blueSlider.isEnabled = false ... } else{ alphaSlider.isEnabled = true redSlider.isEnabled = true greenSlider.isEnabled = true blueSlider.isEnabled = true ... }}
搭配亂數,顯示隨機選色
用button來進行亂數選色:將button連結至程式頁建立action
@IBAction func randomLButton(_ sender: UIButton){
}
有red, green, blue, alpha這4個需要用亂數產出;
定義4個常數並帶入亂數語法
@IBAction func randomLButton(_ sender: UIButton){
let redLrandom = Double.random(in: 0...1) let greenLrandom = Double.random(in: 0...1) let blueLrandom = Double.random(in: 0...1) let alphaLrandom = Double.random(in: 0...1)}
將View.backgroundColor的顏色數值改為CGFloat(亂數常數)
@IBAction func randomLButton(_ sender: UIButton){ ... changeView.backgroundColor = UIColor(displayP3
Red: CGFloat(redLrandom),
green: CGFloat(greenLrandom),
blue: CGFloat(blueLrandom),
alpha: CGFloat(alphaLrandom))}
讓亂數數值連動到Slider與Label:
在randomLButton內變更slider.value;
由於我的顏色slider最大值是255,所以顏色的數值要乘上255
leftAlphaSlider.value = Float(alphaLrandom)leftRedSlider.value = Float(redLrandom) * 255leftGreenSlider.value = Float(greenLrandom) * 255leftBlueSlider.value = Float(blueLrandom) * 255
在randomLButton內添加Label文字變更;
需要整數與小數2位等格式,如下
let redRInt = Int(redLrandom * 255)let greenRInt = Int(greenLrandom * 255)let blueRInt = Int(blueLrandom * 255)alphaLabel.text = String(format:"%.2f", alphaLrandom)redLabel.text = String(redRInt)greenLabel.text = String(greenRInt)blueLabel.text = String(blueRInt)
亂數與漸層搭配
想試試用亂數產生漸層;
且剛好有左右手兩個區塊的silder,在開啟漸層時可以運用!
由於設定漸層時alpha為1,所以只要多增加3個亂數常數
let redRrandom = Double.random(in: 0...1)let greenRrandom = Double.random(in: 0...1)let blueRrandom = Double.random(in: 0...1)
把switch連結至程式頁建立outlet,命名gradationSwitch
@IBOutlet weak var gradationSwitch: UISwitch!
在randomLButton內建立if else
@IBAction func randomLButton(_ sender: UIButton) { ... if gradationSwitch.isOn{
}
else{
}}
先前在switch的func內,可以使用sender .isOn,表示是自己的開關;
但在button的func內,需指明是哪一個變數的開關,故須先將switch建立outlet,才能指明是gradationSwitch.isOn
將先前寫好的內容移至else中,須注意若有共用常數需寫在if 之前
@IBAction func randomLButton(_ sender: UIButton) { let redLrandom = Double.random(in: 0...1)
let greenLrandom = Double.random(in: 0...1)
let blueLrandom = Double.random(in: 0...1)
let alphaLrandom = Double.random(in: 0...1) let redRrandom = Double.random(in: 0...1)
let greenRrandom = Double.random(in: 0...1)
let blueRrandom = Double.random(in: 0...1) if gradationSwitch.isOn{ }
else{ changeView.backgroundColor = UIColor(displayP3
Red: CGFloat(redLrandom),
green: CGFloat(greenLrandom),
blue: CGFloat(blueLrandom),
alpha: CGFloat(alphaLrandom)) }}
再至if 內編寫開啟漸層時內顯示目標,將原來的Layer數值換成亂數常數
graRightLayer.colors = [UIColor.init(displayP3Red: 1, green: 0, blue: 0, alpha: 1).cgColor, UIColor.init(displayP3Red: 0, green: 0.5, blue: 1, alpha: 1).cgColor]
因為在不同func使用同一個常數graRightLayer,
所以要將以下常數放在func外面
let graRightLayer = CAGradientLayer()
if gradationSwitch.isOn{ graRightLayer.frame = rightGraView.bounds graRightLayer.colors = [UIColor.init(displayP3
Red: CGFloat(redRrandom),
green: CGFloat(greenRrandom),
blue: CGFloat(blueRrandom),
alpha: 1).cgColor, UIColor.init(displayP3
Red: CGFloat(redLrandom),
green: CGFloat(greenLrandom),
blue: CGFloat(blueLrandom),
alpha: 1).cgColor] rightGraView.layer.addSublayer(graRightLayer)}
先前開啟漸層時,slider不可用,現在要改成轉換slider用途
原本2個Label:右手美甲,左手美甲,
連結至程式頁建立outlet,命名upLabel, bottomLabel
@IBOutlet weak var upLabel: UILabel!@IBOutlet weak var bottomLabel: UILabel!
修改switch,除了alphaSlider外,讓其他slider可用
@IBAction func funcRiGra(_ sender: UISwitch) { ... if sender.isOn {
alphaSlider.isEnabled = false redSlider.isEnabled = true greenSlider.isEnabled = true blueSlider.isEnabled = true upLabel.text = "上層漸變" bottomLabel.text = "下層漸變" ... } else{ alphaSlider.isEnabled = true redSlider.isEnabled = true greenSlider.isEnabled = true blueSlider.isEnabled = true upLabel.text = "右手美甲" bottomLabel.text = "左手美甲" ... }}
在RGB slider func裡增加if else,將原本內容移至else中,
並在if內增加漸層時的效果
將原本設定Layer時color為固定數值的方式,改為個別的slider.value
@IBAction func greenSliderFunc(_ sender: Any) { if gradationSwitch.isOn { ... graRightLayer.colors = [UIColor.init(displayP3
Red: CGFloat(redSlider.value/255),
green: CGFloat(greenSlider.value/255),
blue: CGFloat(blueSlider.value/255),
alpha: 1).cgColor, UIColor.init(displayP3
Red: CGFloat(leftRedSlider.value/255),
green: CGFloat(leftGreenSlider.value/255),
blue: CGFloat(leftBlueSlider.value/255),
alpha: 1).cgColor] ... } else{ ... }
}
如此,上下漸變的顏色可以根據slider更換
然後再調整button的slider跟label顯示:
在if 內分別顯示上層漸變與下層漸變的數值
@IBAction func randomLButton(_ sender: UIButton) { ... if gradationSwitch.isOn{ ... alphaLabel.text = "1" redLabel.text = String(redRInt) greenLabel.text = String(greenRInt) blueLabel.text = String(blueRInt) alphaSlider.value = 1 redSlider.value = Float(redRrandom) * 255 greenSlider.value = Float(greenRrandom) * 255 blueSlider.value = Float(blueRrandom) * 255 alphaLLabel.text = "1" redLLabel.text = String(redRandom) greenLLabel.text = String(greenRandom) blueLLabel.text = String(blueRandom) leftAlphaSlider.value = 1 leftRedSlider.value = Float(redLrandom) * 255 leftGreenSlider.value = Float(greenLrandom) * 255 leftBlueSlider.value = Float(blueLrandom) * 255 } else{ ... }
}
如此,在開啟漸層時點選隨機選色,可亂數產生漸層(也有單色的可能)
並且漸層的亂數數值可顯示於label
(本次調色切分為3個view,裡面語法更亂一點,但總算先完成效果了)
專案的 GitHub 連結: