2017-10-28 10 views
0

私はSwiftにはかなり新しく、ここでの質問を使用して既に多くのことを学んでいます。Swift 4のDate()が一定時間後にカウントアップとカウントダウンタイマー

私の最初のプロジェクトの1つでは、私はサッカーのプレイタイムタイマーアプリを作成しようとしています。最初のタイマーは、ホイッスルボタンが押された後にカウントアップされ、分が表示され、2番目のタイマーは0にカウントダウンされ、残りの分が表示されます。これまでのところ動作します。

ハーフタイムが終了すると、両方のタイマーが自動的に停止して3番目の時間外タイマーが開始されます。今のところ、タイマの無効化ステートメントは機能していません - 両方のタイマが動作し続けます。 if文には何か問題があるようですが、現時点では私は何の手がかりも持っていません。だから、どんな助けも非常に高く評価されます。

var countUpClock: Timer? 
var countDownClock: Timer? 

private var formatter: DateComponentsFormatter = { 
    let formatter = DateComponentsFormatter() 
    formatter.unitsStyle = .positional 
    formatter.allowedUnits = [.minute, .second] 
    formatter.zeroFormattingBehavior = .pad 
    return formatter 
}() 

func runPlaytimeClocks() { 

    let startTime = Date() 
    let countTime = Date() + 2700 //45min of playtime 

    if startTime <= countTime { 
     countUpClock = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { [weak self] _ in 
     self?.timePlayed.text = self?.formatter.string(from: startTime, to: Date()) 
     } 
    } 
    else { 
     countUpClock?.invalidate() 
     } 


    if startTime <= countTime { 
     countDownClock = Timer.scheduledTimer(withTimeInterval: -1.0, repeats: true) { [weak self] _ in 
      self?.timetoPlay.text = self?.formatter.string(from: Date(), to: countTime) 
      } 
     } 
    else { 
     countDownClock?.invalidate() 
} 
+0

負の時間間隔を設定することはできません。それは、タイマーが過去に1秒間発射することを意味するでしょうか? – Paulw11

+0

あなたのstartTimeがcountTimeに等しい間に行うことができますし、3番目の時間外タイマーを開始することができます。 –

答えて

0

返信いただきありがとうございます。

私はここで探していたまさに見つから:http://ioscake.com/swift-nstimer-in-background.html

私はクロック(CountUpClock、CountDownClock、OvertimeClock、HalftimeClock)のための私の解決策を適応。

サッカーの試合の2番目のハーフタイムを開始するには、最適な解決策は何でしょうか?

これまでのところ、ハーフタイムブレーク後にホイッスルボタンを押すとCountUpClockが0時に開始します。しかし、CountDownClockは45:00から0:00までカウントダウンする必要がありますが、分45:00から90:00までは継続して実行する必要があります。

このような動作に最適なソリューションは何でしょうか?

import UIKit 
import UserNotifications 

private let stopTimeKey = "stopTimeKey" 

class ViewController: UIViewController { 

//Outlets 
@IBOutlet weak var timePlayed: UILabel! 
@IBOutlet weak var timeToPlay: UILabel! 
@IBOutlet weak var overtime: UILabel! 
@IBOutlet weak var halftime: UILabel! 
@IBOutlet weak var halftimeButton: UIButton! 

private var stopTime: Date? 

override func viewDidLoad() { 
    super.viewDidLoad() 

    registerForLocalNotifications() 

    stopTime = UserDefaults.standard.object(forKey: stopTimeKey) as? Date 
    if let time = stopTime { 
     if time > Date() { 
      startTimers(time, includeNotification: false) 
     } else { 
      notifyTimerCompleted() 
     } 
    } 
} 

private func registerForLocalNotifications() { 
    if #available(iOS 10, *) { 
      UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound]) { granted, error in 
      guard granted && error == nil else { 
       // display error 
       print("\(String(describing: error))") 
       return 
      } 
     } 
    } else { 
     let types: UIUserNotificationType = [.badge, .sound, .alert] 
     let settings = UIUserNotificationSettings(types: types, categories: nil) 
     UIApplication.shared.registerUserNotificationSettings(settings) 
    } 
} 
//Actions 
@IBAction func whistleButtonTapped(_ sender: UIButton) { 
    overtimeClock?.invalidate() 
    overtimeClock = nil 
    halftimeClock?.invalidate() 
    halftimeClock = nil 
    overtime.text = "00:00" 
    halftime.text = "00:00" 
    halftimeButton.isHidden = true 
     //add 10 seconds per halftime to try out 
     let time = Date() + 10 
     if time > Date() { 
      startTimers(time) 
     } else { 
      timeToPlay.text = "error" 
     } 
    } 

@IBAction func halftimeButton(_ sender: UIButton) { 
    halftimeButtoPressed() 
} 

// Code for different Timers 

private var countDownClock: Timer? 
private var countUpClock: Timer? 
var overtimeClock: Timer? 
var halftimeClock: Timer? 

private func startTimers(_ stopTime: Date, includeNotification: Bool = true) { 
    // save `stopTime` in case app is terminated 

    UserDefaults.standard.set(stopTime, forKey: stopTimeKey) 
    self.stopTime = stopTime 

    // start Timer 

    countDownClock = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(handleCountDownTimer(_:)), userInfo: nil, repeats: true) 

    countUpClock = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(handleCountUpTimer(_:)), userInfo: nil, repeats: true) 

    guard includeNotification else { return } 

    // start local notification (so we're notified if timer expires while app is not running) 

    if #available(iOS 10, *) { 
     let content = UNMutableNotificationContent() 
     content.title = "Overtime is starting soon" 
     content.body = "In 5 seconds the overtime will start" 
     content.sound = UNNotificationSound.default() 
     //5 seconds warning before overtime starts 
     let trigger = UNTimeIntervalNotificationTrigger(timeInterval: stopTime.timeIntervalSinceNow - 5, repeats: false) 
     let notification = UNNotificationRequest(identifier: "timer", content: content, trigger: trigger) 
     UNUserNotificationCenter.current().add(notification) 
    } else { 
     let notification = UILocalNotification() 
     //5 seconds warning before overtime starts 
     notification.fireDate = stopTime - 5 
     notification.alertBody = "Overtime is starting soon" 
     UIApplication.shared.scheduleLocalNotification(notification) 
    } 
} 

private func stopTimer() { 
    countDownClock?.invalidate() 
    countDownClock = nil 
    countUpClock?.invalidate() 
    countUpClock = nil 
} 

private func halftimeButtoPressed() { 
    overtimeClock?.invalidate() 
    overtimeClock = nil 
    startHalftimeClock() 
    halftimeButton.isHidden = true 
} 

private let dateComponentsFormatter: DateComponentsFormatter = { 
    let _formatter = DateComponentsFormatter() 
    _formatter.allowedUnits = [.minute, .second] 
    _formatter.unitsStyle = .positional 
    _formatter.zeroFormattingBehavior = .pad 
    return _formatter 
}() 

@objc func handleCountDownTimer(_ timer: Timer) { 
    let now = Date() 

    if stopTime! > now { 
     timeToPlay.text = dateComponentsFormatter.string(from: now, to: stopTime!) 
    } else { 
     stopTimer() 
     notifyTimerCompleted() 
     startOvertimeClock() 
     halftimeButton.isHidden = false 
    } 
} 

@objc func handleCountUpTimer(_ timer: Timer) { 
    //add 10 seconds per halftime to try out 
    let now = Date() + 10 

    if now > stopTime! { 
     timePlayed.text = dateComponentsFormatter.string(from: stopTime!, to: now) 
    } else { 
     stopTimer() 
     notifyTimerCompleted() 
    } 
} 

//Overtime Clock 
@objc func startOvertimeClock() { 

    let startOvertime = Date() 

    overtimeClock = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { [weak self] _ in 
     self?.overtime.text = self?.dateComponentsFormatter.string(from: startOvertime, to: Date()) 
    } 
} 

//Halftime Clock 
@objc func startHalftimeClock() { 

    let startHalftime = Date() 

    halftimeClock = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { [weak self] _ in 
     self?.halftime.text = self?.dateComponentsFormatter.string(from: startHalftime, to: Date()) 
    } 
} 

private func notifyTimerCompleted() { 
    timeToPlay.text = "End" 
    timePlayed.text = "End" 
} 

} 
関連する問題