平時用戰網安全令的時候很喜歡圓形倒計時的效果,然後簡單看了一下Android的圓形進度條,後來又寫了一個IOS的。整體界面參照IOS系統的倒計時功能,順便熟悉了UIPickerView的一些特性的實現方法。完整代碼可以看:Github。
其實沒什麼難度,下面記錄幾個要點
本文地址:http://www.cnblogs.com/rossoneri/p/4868606.html
放個預覽圖
用的貝塞爾曲線UIBezierPath來畫,這個類支持畫很多種形狀,可以單獨去嘗試。
UIBezierPath *progress = [UIBezierPath bezierPath];
[progress addArcWithCenter:CGPointMake(rect.size.width / 2, rect.size.height / 2)
radius:RADIUS
startAngle:startAngle
endAngle:endAngle
clockwise:YES];
progress.lineWidth = PROGRESS_WIDTH;
[[UIColor redColor] set];
[progress stroke];
參數分別為圓心點、半徑、繪制起始角度、繪制結束角度、順時針方向。如果畫一個整圓,角度設為0,2pi即可。這裡0度對應3點鐘方向,我希望繪制從12點方向開始,設置起始角度為-0.5pi即可。結束角度就根據經過的時間和總的時間的比例進行角度計算。有了以上參數也可以算出在當前角度下的圓周上點的坐標,即可以畫出那個圓點。
這裡為了繪制看起來更連貫,我選擇0.05秒刷新一次界面,而沒有參考系統定時器的1秒刷新一次,這樣看起來會更舒服。但在顯示數字上會遇到1秒的誤差,所以我在格式化字符串的時候對剩余時間做了向上去整ceil()
的操作,具體差別可以通過改代碼來嘗試。
m_timer = [NSTimer scheduledTimerWithTimeInterval:TIMER_INTERVAL target:self selector:@selector(setProgress) userInfo:nil repeats:YES];
我一直以為iOS的滾輪是支持內容循環顯示的,然而並沒有看到相關接口,所以有點迷茫。查過資料後發現原來是用了一個技巧,即循環設置非常多的滾輪內容,然後默認選擇居中的item,比如設置10000個項,內容是:0,1,2, ..., 97, 98, 99, 0, 1, 2, ..., 97, 98, 99, ...,然後默認顯示第5000個條目,這樣用戶劃起來就好像是循環的。因為總的內容很多,用戶不會劃很多次,所以用戶一般不會遇到劃到頭的情況。於是,我在系統計時器裡試了一下,的確是這樣的,當我往一個方向劃動非常多次後,滾輪還是會到頭的。所以這是可行的方法。
//這裡可以直接用MAX_ROWS / 2,但下面的計算適合各種情況:取中間位置,取整,再取余根據余數校正起始位置為要顯示內容的第一項(即選中居中的 0 的位置)
- (void)init {
[m_pickerView selectRow:(((NSInteger)((MAX_ROWS / 2) / [m_arrayData count])) * [m_arrayData count]) + (selectedRow % [m_arrayData count]) inComponent:0 animated:NO];
}
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return MAX_ROWS;
}
系統定時器在選擇數字的時候,右邊會有一個固定的單位。我依然沒有在UIPickerView中找到設置固定單位的接口。如果在-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)componet
方法裡加上單位,則效果是每一項都會有這個單位。為了解決這個問題,我先嘗試了第一種方法,即返回兩列滑輪,第二列只有一行:“分鐘”,這樣顯示效果沒問題,但第二列是可以拖動的,即有邊界彈性效果,而且系統也沒有提供關閉彈性效果的接口(btw:UIScrollView裡有)。因為這個效果和系統定時器的不一樣,所以棄用,不過代碼裡依然遺留。第二個方案就是直接貼一個Label
到適當的位置。簡單粗暴,就是位置坐標需要調整到完美顯示。不過把它封裝成一套控件,往後就可以隨意使用了。
參考資料因為chrome沒設置同步歷史記錄,所以這台電腦上沒有,改天抽空補上
完整代碼可以看:Github
自定義AlertView用的是開源的項目:GithubWritten with StackEdit.