IOS小組件實現時鐘按秒刷新功能

引言

  上一節中我們瞭解瞭IOS小組件的刷新機制,發現根本沒法實現按秒刷新,但是看別的App裡面有做到,以為用瞭什麼黑科技,原來是因為系統提供瞭一個額外的機制實現時間的動態更新,不用走小組件的刷新機制。

Text控件支持顯示日期時間,下面是來自官網的代碼

計算時間差

let components = DateComponents(minute: 11, second: 14)
let futureDate = Calendar.current.date(byAdding: components, to: Date())!

Text(futureDate, style: .relative)
// Displays:
// 11 min, 14 sec

Text(futureDate, style: .offset)
// Displays:
// -11 minutes

  使用relative樣式可以顯示當前日期和時間與指定日期之間的差值(絕對值),而不管該日期是將來的還是過去的日期。使用offset樣式顯示當前日期和時間與指定日期之間的時差,表示將來的日期帶有減號(-)前綴,而過去的日期帶有加號(+)前綴。

倒計時和計時器

let components = DateComponents(minute: 15)
let futureDate = Calendar.current.date(byAdding: components, to: Date())!

Text(futureDate, style: .timer)
// Displays:
// 15:00

  對於將來的日期,timer樣式將遞減計數(倒計時),直到當前時間達到指定的日期和時間為止,並在日期經過時遞增計數(計時器)。

顯示絕對日期或時間

// Absolute Date or Time
let components = DateComponents(year: 2020, month: 4, day: 1, hour: 9, minute: 41)
let aprilFirstDate = Calendar.current(components)!

Text(aprilFirstDate, style: .date)
Text("Date: \(aprilFirstDate, style: .date)")
Text("Time: \(aprilFirstDate, style: .time)")

// Displays:
// April 1, 2020
// Date: April 1, 2020
// Time: 9:41AM

顯示兩個日期之間的時間間隔

let startComponents = DateComponents(hour: 9, minute: 30)
let startDate = Calendar.current.date(from: startComponents)!

let endComponents = DateComponents(hour: 14, minute: 45)
let endDate = Calendar.current.date(from: endComponents)!

Text(startDate ... endDate)
Text("The meeting will take place: \(startDate ... endDate)")

// Displays:
// 9:30AM-2:45PM
// The meeting will take place: 9:30AM-2:45PM

實現一天時間的計時器

  使用 style: .time樣式,如果當前的時間比指定的時間大,則時間就會累計。基於這個原理,我們隻需要把時間起點定在每天的0點即可,根據當前的時間計算出今天的開始時間。以下方法可以根據12,24小時制度,獲取當天起點時間。

//獲取當天開始的日期,給Date增加一個拓展方法
 extension Date {
    func getCurrentDayStart(_ isDayOf24Hours: Bool)-> Date {
        let calendar:Calendar = Calendar.current;
        let year = calendar.component(.year, from: self);
        let month = calendar.component(.month, from: self);
        let day = calendar.component(.day, from: self);
    
        let components = DateComponents(year: year, month: month, day: day, hour: 0, minute: 0, second: 0)
        return Calendar.current.date(from: components)!
    }
}
// 實現一天內的計時器
Text(Date().getCurrentDayStart(true), style: .timer)

結語

  通過IOS Text控件我們實現瞭按秒刷新的計時器,所以數字時鐘的按秒刷新算是解決瞭,但是怎麼實現表盤時鐘的秒針360度旋轉呢?如果讓秒針精確的對應當前的時間,應該做不到瞭。後面再繼續研究,如果有解決方案的可以貢獻一下,感謝。

推薦閱讀: