平時用戰(zhàn)網(wǎng)安全令的時候很喜歡圓形倒計時的效果,然后簡單看了一下Android的圓形進(jìn)度條,后來又寫了一個IOS的。整體界面參照IOS系統(tǒng)的倒計時功能,順便熟悉了UipickerView的一些特性的實現(xiàn)方法。完整代碼可以看:Github。
其實沒什么難度,下面記錄幾個要點
本文地址:http://m.survivalescaperooms.com/rossoneri/p/4868606.html
放個預(yù)覽圖

用的貝塞爾曲線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];參數(shù)分別為圓心點、半徑、繪制起始角度、繪制結(jié)束角度、順時針方向。如果畫一個整圓,角度設(shè)為0,2pi即可。這里0度對應(yīng)3點鐘方向,我希望繪制從12點方向開始,設(shè)置起始角度為-0.5pi即可。結(jié)束角度就根據(jù)經(jīng)過的時間和總的時間的比例進(jìn)行角度計算。有了以上參數(shù)也可以算出在當(dāng)前角度下的圓周上點的坐標(biāo),即可以畫出那個圓點。
這里為了繪制看起來更連貫,我選擇0.05秒刷新一次界面,而沒有參考系統(tǒng)定時器的1秒刷新一次,這樣看起來會更舒服。但在顯示數(shù)字上會遇到1秒的誤差,所以我在格式化字符串的時候?qū)κS鄷r間做了向上去整ceil()的操作,具體差別可以通過改代碼來嘗試。
m_timer = [NSTimer scheduledTimerWithTimeInterval:TIMER_INTERVAL target:self selector:@selector(setProgress) userInfo:nil repeats:YES];我一直以為iOS的滾輪是支持內(nèi)容循環(huán)顯示的,然而并沒有看到相關(guān)接口,所以有點迷茫。查過資料后發(fā)現(xiàn)原來是用了一個技巧,即循環(huán)設(shè)置非常多的滾輪內(nèi)容,然后默認(rèn)選擇居中的item,比如設(shè)置10000個項,內(nèi)容是:0,1,2, ..., 97, 98, 99, 0, 1, 2, ..., 97, 98, 99, ...,然后默認(rèn)顯示第5000個條目,這樣用戶劃起來就好像是循環(huán)的。因為總的內(nèi)容很多,用戶不會劃很多次,所以用戶一般不會遇到劃到頭的情況。于是,我在系統(tǒng)計時器里試了一下,的確是這樣的,當(dāng)我往一個方向劃動非常多次后,滾輪還是會到頭的。所以這是可行的方法。
//這里可以直接用MAX_ROWS / 2,但下面的計算適合各種情況:取中間位置,取整,再取余根據(jù)余數(shù)校正起始位置為要顯示內(nèi)容的第一項(即選中居中的 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;}系統(tǒng)定時器在選擇數(shù)字的時候,右邊會有一個固定的單位。我依然沒有在UIPickerView中找到設(shè)置固定單位的接口。如果在-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)componet方法里加上單位,則效果是每一項都會有這個單位。為了解決這個問題,我先嘗試了第一種方法,即返回兩列滑輪,第二列只有一行:“分鐘”,這樣顯示效果沒問題,但第二列是可以拖動的,即有邊界彈性效果,而且系統(tǒng)也沒有提供關(guān)閉彈性效果的接口(btw:UIScrollView里有)。因為這個效果和系統(tǒng)定時器的不一樣,所以棄用,不過代碼里依然遺留。第二個方案就是直接貼一個Label到適當(dāng)?shù)奈恢谩:唵未直褪俏恢米鴺?biāo)需要調(diào)整到完美顯示。不過把它封裝成一套控件,往后就可以隨意使用了。
參考資料因為Chrome沒設(shè)置同步歷史記錄,所以這臺電腦上沒有,改天抽空補上
完整代碼可以看:Github
自定義AlertView用的是開源的項目:GithubWritten with StackEdit.
新聞熱點
疑難解答