最近工作上需要用到ratingBar 但是iOS不像Android 已經有內建的ratingBar control可以使用,所以自己建了一個,主要是參考apple官方的這篇文章,
然後改善了一些靈活性,讓更多的rating control屬性可以在design interface上去做設定,還有新增讓使用者按著拖曳評分的功能。
新增一個Cocoa Touch Class
這裡override init(frame:)跟實作init(coder:)
init(frame:) 是在程式碼創建時,會去執行setupButtons()
因為我們override init(frame:) 自動喪失繼承所有init的特性,必須在實作super class 標記成required的init也就是init(coder:)
init(coder:) 是在storyboard創建時,會去執行setupButtons()
setupButtons()是我們等下要設定button也就是在畫面上星星的function
拉一個Horizontal Stack View到StoryBoard上,設定class為我們剛剛創建的RatingControl
接下來宣告Properties
ratingButtons是用來儲存待會會用到的星星Button
rating是給使用者輸入一開始評分的起始值,之後也可以藉由這個屬性取得目前評分值
fillImage、halfImage、emptyImage是全顆星、半顆星、空星星的圖片設定屬性
starSize 是設定我們星星Size
starCount是設定我們星星的數量
以上的屬性都是@IBInspectable,在每個Properties設定didSet去執行setupButtons()使得我們在design interface上做設定時,能得到畫面上立即的反應,增加靈活度,可視性
接著新增一個setupButtons() Method
setupButtons方法主要是把Button加入到我們剛剛的View中
10行是根據starCount這個屬性去生成幾個button
12,13行是限制button的寬高,使用到starSize這個屬性
15~22行是根據rating這個屬性去判斷輸入的Star起始值
25行是因為待會要做讓使用者能TouchMove以拖曳的方式設定分數,所以要把button的isUserInteractionEnabled設為false,如果不設為false,使用者點到button進行拖曳時會無法觸發TouchMove 的事件。
接下來要做當使用者按著RatingBar 時左右滑動rating也會跟著做動
先override兩個方法touchesBegan 和 touchesMoved
在這兩個方法中我們主要會去取得到使用者按下和按下不放時的(x,y)座標然後去執行updateButtonSelectionStates這個方法去更新畫面
這個方法主要是根據我們剛剛在TouchMove and TouchBegan抓到的point去做畫面上圖片的更新
2行是取得我們設定的button寬度一半的size,因為我們要做半顆星判斷
3~13 行我們每個button去判斷在TouchMove and TouchBegan取到的point座標去判斷目前滑到的分數,存入ratingTemp中,在指定給rating觸發didset 的setButtons。
最後宣告一個public 方法getRating去取得分數
到這就完成,我們看一下storyBoard上的畫面
Rating Control那欄可以設定rating你的起始分數,fill Image 、half Image、empty Image跟星星的大小還有數量,Stack View的spacing可以調整星星之間的距離。
最後給點小提示,因為有宣告IBInspectable 的property,使得Xcode會一直去rebuild相當煩人,可以在這裡去關掉他Automatically Refresh Views 他就不會一直rebuild了。
sample: