我正在創建一個應用程式,我必須在主螢屏上顯示點,但用戶必須解鎖點才能觀看它,并且它的標簽開始計數器 60secs 。這是我的定時器功能。
timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(updateCounter), userInfo: nil, repeats: true)
@objc func updateCounter() {
if counter > 0 {
let time = Int(counter/60)
let dec = Int(counter.truncatingRemainder(dividingBy: 60))
spotTiming = String(time) ":" String(dec)
}
counter -= 1
}
這就是它在螢屏上的顯示方式
在任何一個點上錄音后,計數器將開始。但我的問題是如何在超過 2 個具有相同計數器功能的標簽上啟動計數器。因為用戶可以以 10 秒的差異點擊 2 個不同的點,而我只有一個計數器功能,所以我如何設法啟動 2 個不同的計數器。有沒有其他人可以建議的方法,所以我將非常感激!謝謝你。 PS Spots 可以是多個,具體取決于用戶。
uj5u.com熱心網友回復:
假設您希望每個“點”在被點擊時開始“從 60 開始倒計時”,這里有一個簡單的例子......
我們將創建一個UIView帶有標簽和圓形邊框的子類。
它還將有一個“startTime”屬性:
private var startTime: Date?
當我們點擊視圖時,我們將開始時間設定為“現在”:
startTime = Date()
我們將有一個更新倒計時的功能:
public func timerFired(_ now: Date) {
if let st = startTime {
let elapsedSeconds = Int(floor(now.timeIntervalSinceReferenceDate - st.timeIntervalSinceReferenceDate))
label.text = "\(60 - elapsedSeconds)"
// if we've reached 60-seconds, set startTime to nil
// so we don't keep going to -1, -2, -3 etc
if elapsedSeconds == 60 {
self.startTime = nil
}
}
}
在我們的控制器中,我們將有一個每 0.3 秒觸發一次的重復計時器。如果我們每秒只觸發一次,我們可以“跳過”數字:
// use less-than 1-second for the timeInterval... otherwise, we *could* end up with
// skipped seconds. That is, we might see "60 59 58 56 55 53 etc"
Timer.scheduledTimer(timeInterval: 0.3, target: self, selector: #selector(timerFunc), userInfo: nil, repeats: true)
每次 timer func 觸發時,我們都會通過呼叫來告訴每個“spot”視圖.timerFired(),然后“spot”視圖會將自己startTime的時間與新時間進行比較并更新其標簽。
所以,這是我們的自定義SpotView類:
class SpotView: UIView {
private var startTime: Date?
private let label = UILabel()
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
private func commonInit() {
label.numberOfLines = 0
label.text = "Unlock\nto See"
label.textAlignment = .center
label.translatesAutoresizingMaskIntoConstraints = false
addSubview(label)
NSLayoutConstraint.activate([
label.centerXAnchor.constraint(equalTo: centerXAnchor),
label.centerYAnchor.constraint(equalTo: centerYAnchor),
])
layer.borderColor = UIColor.red.cgColor
layer.borderWidth = 1
let g = UITapGestureRecognizer(target: self, action: #selector(gotTap(_:)))
addGestureRecognizer(g)
}
override func layoutSubviews() {
super.layoutSubviews()
let m: CGFloat = min(bounds.width, bounds.height)
layer.cornerRadius = m * 0.5
}
@objc func gotTap(_ g: UITapGestureRecognizer) {
// set the startTime property to "now"
startTime = Date()
label.text = "60"
}
public func timerFired(_ now: Date) {
if let st = startTime {
let elapsedSeconds = Int(floor(now.timeIntervalSinceReferenceDate - st.timeIntervalSinceReferenceDate))
label.text = "\(60 - elapsedSeconds)"
// if we've reached 60-seconds, set startTime to nil
// so we don't keep going to -1, -2, -3 etc
if elapsedSeconds == 60 {
self.startTime = nil
}
}
}
}
和一個示例控制器:
class FourSpotsVC: UIViewController {
var theSpots: [SpotView] = []
override func viewDidLoad() {
super.viewDidLoad()
let w: CGFloat = 100.0
let h: CGFloat = 100.0
var x: CGFloat = 40.0
var y: CGFloat = 100.0
// let's add 4 "Spot" views
for i in 0..<4 {
x = i % 2 == 0 ? 40.0 : 160.0
let v = SpotView()
v.frame = CGRect(x: x, y: y, width: w, height: h)
view.addSubview(v)
theSpots.append(v)
y = h 20.0
}
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// use less-than 1-second for the timeInterval... otherwise, we *could* end up with
// skipped seconds. That is, we might see "60 59 58 56 55 53 etc"
Timer.scheduledTimer(timeInterval: 0.3, target: self, selector: #selector(timerFunc), userInfo: nil, repeats: true)
}
@objc func timerFunc() {
let n = Date()
theSpots.forEach { v in
v.timerFired(n)
}
}
}
運行時看起來像這樣(我點擊了 Top Spot,然后等待了大約 10 秒并點擊了 Second Spot):

轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/507553.html
上一篇:如何以間隔從SFSafariViewController中的UITextField打開用戶的URL鏈接(任何鏈接)?/斯威夫特5
