iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 13
1
自我挑戰組

Hey! UIKit, 做個朋友吧~系列 第 13

Day 13: 我碰了UISlider~就~咻的滑過去了

  • 分享至 

  • xImage
  •  

不...不是,拜託大大不要吉我QQ


UISlider是用來在一個連續範圍中選取單一數值。

(圖片來源:UISlider)

Slider對應的UIEvent為value change,當使用者滑動thumb的時候,slider的值會改變並送出valueChange的event,這時如果你有為slider設定target-action,slider便會將新值送給這個action並執行。

slider的外觀是可以被客製化的,你可以為thumb跟track指定新顏色,也可以在slider的頭尾設定圖片。

創建slider的步驟如下:

  • 設定slider的數值範圍。
  • 設定slider的外觀,你高興就好。
  • 為slider指定一個或多個target-action。
  • 設定auto layout。

Attribute

Minimum / Maximum / Current Value

設定slider的數值範圍及初始位置。
使用minimumValue設定最小值,maximumValue設定最大值,value則決定了slider的初始數值及thumb的當前位置。
需要注意的是,value一定要介於最大值和最小值之間,如果當前值超出了這個範圍,將會更新slider的最大值或最小值。

newSlider.minimumValue = 0
newSlider.maximumValue = 100
newSlider.value = 70

設定一個function讓slider傳送當前值給label,再將此function作為slider的target-action,每當slider的value改變時便會執行。

@objc func changeLabel(_ sender: UISlider) {
    valueLabel.text = "\(Int(sender.value))"
}

Image / TintColor

slider可以對minimum及maximum的兩側指定圖片:

newSlider.maximumValueImage = UIImage(named: "louder")
newSlider.minimumValueImage = UIImage(named: "lighter")


也可以對track以及thumb各自指定圖片及顏色。但是thumb跟track的image和color可以說是一山不容二虎,只要你指定了tint color,原先設定的image就會被踢下去;反之設定了image,tint color就會被移除。

newSlider.minimumTrackTintColor = UIColor.red
newSlider.maximumTrackTintColor = UIColor.blue
newSlider.thumbTintColor = UIColor.yellow
newSlider.setThumbImage(UIImage(named: "finn"), for: .normal)


(阿寶就這樣活生生的把yellow thumb踢下去,有夠兇殘。)

slider的高度會受你的圖片影響,即使你事先給定slider高度,在指定圖片時若圖片高度大於slider高度,將會取代預設的高度而不會對圖片進行壓縮。

newSlider.setMaximumTrackImage(UIImage(named: "blue"), for: .normal)
newSlider.setMinimumTrackImage(UIImage(named: "yellow"), for: .normal)


而max track的圖片是固定於底層的,min track的圖片則會隨著thumb壓縮。

大家應該有發現另外一件事,就是我在設定thumb/track image的時候是需要指定state的,所以你可以設定在不同的state下顯示不一樣的圖片。或像範例一樣設定thumb color,再設定某一個狀態下用image覆蓋,這麼一來在切換狀態(拖移)時就會顯示/隱藏圖片了。

Continuous Updates

前面的範例可以看的出來,當使用者滑動thumb的時候,slider value的變動是連續的,並連續送出valueChange的event。但如果將isContinuous設為false的話,只有在使用者放開thumb的時候才會送出event,並傳送最終的值。

Step Slider

有時候會看到固定間距的slider。

其實這個做法很簡單,先設定一個step:

let step: Float = 10

step要指定型別為float,因為value的型別為Float,如果不指定的話整數預設型別為Int,會無法與value進行運算。

接下來想像一下,要怎麼讓數字都顯示為step的倍數?

step的倍數顧名思義就是step本身乘以一個整數,所以可以先將value值除以step,取整數的部分再乘以step回去。
以範例來說step為10,那0.00 ~ 9.99之間的數除以10之後的整數部份都為0,而10.00 ~ 19.99除以10之後的整數部分都為1,所以乘10之後,10.00 ~ 19.99的value都會顯示10。

所以將之前changeValue的function裡valueLabel的text做一些修改:

valueLabel.text = "\(Int(round(sender.value / step) * step))"

就可以達到demo的效果。

Internationalization

slider本身跟國際化一點關係也沒有,但你如果有像範例一樣連動label的話,記得要注意label的internationalization。
slider會自動調整自己的位置,以確保最小值跟最大值的位置。但如果你有複寫minimumValueImageRect(forBounds:)或是maximumValueImageRect(forBounds:)的話,需要注意一下最大值及最小值的位置。

Accessibility

當VoiceOver開啟時,使用者若於slider上下滑動(非左右滑動),系統便會回饋標籤、當前值、特徵以及使用提示給使用者。
例如使用者上下滑動音量調整的slider時,系統會回饋"Sound volume: 13 percent. Adjustable. Swipe up or down with one finger to adjust the value.”

那下一回就是IBAction七仙女的最後一位-UISwitch。
終於要講完IBAction家族了,真有成就感~


上一篇
Day 12: UITextField三部曲-直搗工作室的UITextField
下一篇
Day 14: 到底要on還是要off?選擇障礙的我與UISwitch
系列文
Hey! UIKit, 做個朋友吧~30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
ytyubox
iT邦新手 5 級 ‧ 2019-09-28 11:10:47

可以看看 StepSlider, 很有趣! https://github.com/spromicky/StepSlider

黑貓仔 iT邦新手 5 級 ‧ 2019-09-28 16:44:40 檢舉

我之前有看過~但文件沒寫到我就忽略了。
我要把它加進文章裡❤️

我要留言

立即登入留言