要調幾次、隨機、重來都可以!恐龍的帽子調色進階版─調色大師 APP
◆課堂練習&作業10–1:調色大師─Outlet & Action+亂數應用◆
繼之前練習過的 在 Playground 去背調色 之後,這次是更進階的練習, 結合 IBOutlet 跟 IBAction 的應用客製化整張圖片 (ง๑ •̀_•́)ง
不只可以隨時改變帽子顏色,背景色、圓角、陰影、邊框全都可以調整到滿意為止!
製作內容:
1.利用 Slider 調整顏色&Label 顯示顏色數值
2. 多個區塊的調色(利用 Segmented Control 控制)
3.加入顏色隨機按鈕(random)及重新調色按鈕
4.利用 Slider 調整圖片的圓角、陰影、邊框
5.設定 Switch可用/不可用、打開 Switch 時才顯示可用的按鈕或是 Slider
6.用按鈕將花紋加到圖片上
7.應用寫在外面的變數來儲存東西
成品
製作記錄:外觀部分
【設置按鈕邊框顏色】
直接輸入 layer.borderColor
、Type 設為 Color 選色後仍然跑不出邊框顏色
因為從 Type 設置的 Color 型別是 UIColor,而邊框顏色的型別是用 CGColor,因此要新增一個 file 讓預設的 UIColor 變成邊框需要的 CGColor
步驟 1:點選 File→New→New File(快捷 cmd+N)會跳出下面的視窗,選擇 Objective-C File 後按下一步
步驟 2:第二個視窗,File 名可自行填寫,File Type 選 Category,最下面的 Class 要自己手動輸入 CALayer,輸入完畢後點下一步就創好新的檔案了
步驟 3:此時右邊會多兩個檔案,分別是 xxxx.h
跟 xxxx.m
,點入 xxxx.m
的那個檔案,並貼上下面程式碼
#import “CALayer+borderColor.h”
#import <UIKit/UIKit.h>
@implementation CALayer (borderColor)
- (void)setBorderColorWithUIColor:(UIColor *)color
{
self.borderColor = color.CGColor;
}@end
有部分程式碼其實是創立檔案時就寫好的(例如第一行 #import 跟最後一行 @end ) 但直接整段覆蓋避免出錯比較安全
步驟 4:可以正大光明的在設置的視窗輸入 layer.borderColor
並選色啦!(也要加入 layer.borderWidth
才能有邊框寬度&要開模擬器才看得到)
參考文章:
【同時製作圖片圓角跟陰影】
同時擁有陰影跟圓角,要建立一個新的 view(ShadowView)來設置陰影,並且把要設定圓角的圖片(DinoBackgroundImageView)包在裡面
並且將 Shadow View 的 Background Color 需設為白色,陰影的顏色是透過 .layer.shadowColor = UIColor.darkGray.cgColor
這行程式碼來產生,ShadowView 設置的 Background Color 跟陰影顏色無關
設為白色是因為此時圖片(DinoBackgroundImageView)是去背過可以調色的,調色時若把透明度調為 1 以下,如果 ShadowView 的背景設為其他顏色會覆蓋上該顏色,設置為 clear 則會蓋上陰影色(用下面圖片說明比較好懂)
整體來說需要設置語法的部份為:
【設圓角的 ImageView(DinoBackgroundImageView)】
.clipsToBounds = true
+圓角語法
【陰影 View(ShadowView)】
陰影相關語法(顏色、位置、銳利度等)+圓角語法
陰影的 View 也要設置圓角,這樣圖片在拉圓角時才不會因為被擋住而破圖
製作記錄:功能部分
【IBAction 的語法注意點】
IBAction 中寫觸發哪個元件,裡面的內容就只專注於觸發後的動作
例如:觸發 SwitchOn,裡面的動作就專注寫「開關打開之後會有哪些動作」,不要貪心在裡面寫切換 SegmentControl 會出現的動作
SegmentControl 的切換所觸發的動作就寫在 SegmentControl 的 IBAction 裡,SwitchOn 就只寫開關打開時的動作,程式整體上也比較不混亂
會發現自己寫有這個問題,是因為功能設定為:
花色的Switch只有停留在帽子SegmentControl的時候可以使用&開啟,打開後會跑出花紋的按鈕可以選擇。而切換到其他兩個SegmentControl(調整背景&邊框色)時會讓Switch無法使用&開啟,也會隱藏按鈕但一開始寫程式時卻在SwitchOn這個IBAction裡面,用if寫進切換到其他SegmentControl時的內容,例如Switch無法使用、Button會隱藏等設定,然後就出現了Bug(笑)因為SwitchOn這個IBAction只管開關有沒有開
【花紋設置】
原本想要像〈我家的貓貓最可愛!〉這篇文一樣,使用 tintColor 來改花紋色,但是在無限的卡關後發現了盲點:
雖然可以加上花紋,但是無法調花紋的顏色!因為沒有製作調整花紋顏色用的 Slider(上面的 Slider 動了就會影響帽子顏色,因為他是屬於帽子的調色 Slider)
除非像貓貓文中一樣,純色製作一份調色 Slider、花紋處也製作一份調色 Slider,或是將花紋功能移至其他 SegmentControl,才能製作出調整花紋顏色的功能
最後放棄調花紋顏色的功能,直接將花紋圖片覆蓋在帽子的顏色上。設定原本圖片的 tintColor,並用灰色系&透明度調低,讓墊在下面的帽子色能透出來一點點這裡不用把花紋墊在底下的方式,是因為如果按了按鈕,若當時帽子的透明度為 1,導致顏色蓋住而看不到花紋,操作上不夠直觀&麻煩(按了就是想要馬上看套花紋上去的效果啊 XD)
【各個顏色的隨機按鈕】
一開始一直糾結在 UIColor 沒有只改變單個顏色的語法(如果沒有卡住就不會寫進製作記錄XD)後來靈光一閃,那就讓其他沒有要隨機的顏色停留在原本 Slider 的 Value 就好啦!
【用變數儲存值】
卡最久的部分,這個應用在兩個部分:
- 因為帽子、背景、邊框在未調色前的預設顏色都不同,想要在切換 SegmentControl 時,顯示預設色在 Slider 上相對應的位置。但是進行調色後,即使切換到其他 SegmentControl 再回來,也會停留在上次調整後的位置
- 修復花紋 Switch 的 Bug(未修復前:SwitchOn+選花色後,切換到其他 SegmentControl 再回來,雖然花紋還會印在圖上,但是 Switch 會顯示為Off)
利用寫在外面的變數來儲存資料,不管在哪個 function 中都能寫入想要的值或是將變更後的值再存回變數中
1. Slider 部分
因為一個變數只能寫一個值,3 個調色物件(帽子、背景、邊框)各有 4 種值(紅色、綠色、藍色、透明度)所以總共要設置 12 個變數,並且在宣告時先填入該色的預設值,這個預設值是用在「使用者未調色前」會顯示的 Slider 位置
一開始雖然知道變數後面只能寫值,但莫名的腦袋打結不知道該怎麼寫(一直連結 UIColor 寫 RGB 的寫法)其實顏色也是值啊,就是 RGB 的數字,例如:R: 43/255 G: 44/255 B: 243/255,所以才需要各選項各寫一個變數不能共用
另外,Slider 的型別是 Float
,所以在寫變數時先改變型別為 Float,就不用之後一直包括號轉換
而顏色的 Slider 值設定在 0~1,這裡用 xx/255
的方式表示是因為寫法更直覺(平常顏色也都是用這種寫法,再讓程式去運算)且之後要換預設色就不用再手動計算一次(直接改寫前面 xx 的值就可以)
只要有變更值的動作(觸發 IBACtion func colorSliderChange 時)就要將新的值存入變數中,再透過 SetValue 的 function 讓 Slider 跳到該值的位置
沒有變更值的時候(使用者未調整顏色,因此不會觸發 IBACtion func colorSliderChange)因為當時變數沒有存入其他值,所以使用預設值呈現
文字描述有點複雜,總之在觸發動作前使用預設值(宣告時寫的值),觸發後則存入新的值。就能呈現出想達到的:切換 SegmentControl 時顯示預設顏色的位置,調色後會停留在上次調整後的位置
2. Switch 部份
容我先跳過,懂歸懂但還無法用好理解的方式寫出來 😂 (光 Slider 那串都覺得像是繞口令 XD)
不過觀念是一樣的:先做一個預設值,觸發其他動作時再去存入新的值,只是這次填入的值 true 或 false 不是數字
【完整程式碼@GitHub】
整篇記錄寫完發現,卡關部分大多因為觀念還不夠清楚,應用上不夠精確才會「想做的功能用程式做出來後,卻沒有達到預期成果」。゚ヽ(゚´Д`)ノ゚。
Coding 完成後,還是覺得有哪邊可以整合成幾行就搞定,例如:各色隨機按鈕部分,落落長但是內容都差不多。礙於時間關係(這篇拖太久 XD)先求有然後還不差就好,等之後功力進步再慢慢簡化,不然作業進度落後太多啦 レ(゚∀゚;)ヘ
最後的反思時間,花紋雖然隨著關閉 Switch 就會消失(當時想說只有兩個花紋,不用特定做清除功能)但是更進階的還能製作:1.按一下跑出花紋,按第兩下花紋消失,按第三下花紋又出現
2.Switch 關閉後再打開,花紋會出現並選擇上次的設置
另外,推薦卡很久的時候換個環境寫看看。之前在家寫卡了好幾天,怎麼想腦袋就是運轉不過來。隔天因為在等空檔跑去咖啡廳寫,兩三小時就把之前卡兩三天的部份都搞定 XD