2016-05-31 8 views
0

Ich habe eine UIDatePicker, die nur auf die Zeit beschränkt ist. Die App speichert die ausgewählte Zeit aus dem DatePicker in einer Variablen und wenn diese Zeit erreicht ist, wird eine UILocalNotification ausgelöst.Zählzeit von der aktuellen Zeit bis zur bestimmten Zeit

So gibt es ein Etikett, das die verbleibende Zeit bis zur lokalen Benachrichtigung anzeigt. Es funktioniert im Prinzip wie ein Countdown-Timer. Wie kann ich das erreichen?

Date String: (für die fireDate Anzeigen)

func formatTimeForDisplay(date:NSDate) -> String { 
     let formatter = NSDateFormatter() 
     formatter.locale = NSLocale.currentLocale() 
     formatter.timeStyle = NSDateFormatterStyle.ShortStyle 
     return formatter.stringFromDate(date) 
     } 

Erweiterung für NSLocalNotification: (für die NSDate von UIDatePicker zu fireDate für die LocalNotification Umwandlung)

extension NSDate { 
    var minute: Int { 
     return NSCalendar.currentCalendar().component(.Minute, fromDate: self) 
    } 
    var hour: Int { 
     return NSCalendar.currentCalendar().component(.Hour, fromDate: self) 
    } 
    var day: Int { 
     return NSCalendar.currentCalendar().component(.Day, fromDate: self) 
    } 
    var month: Int { 
     return NSCalendar.currentCalendar().component(.Month, fromDate: self) 
    } 
    var year: Int { 
     return NSCalendar.currentCalendar().component(.Year, fromDate: self) 
    } 
    var fireDate: NSDate { 
     let today = NSDate() 
     return NSCalendar.currentCalendar().dateWithEra(1, 
                 year: today.year, 
                 month: today.month, 
                 day: { hour > today.hour || (hour == today.hour 
                  && minute > today.minute) ? today.day : today.day+1 }(), 
                 hour: hour, 
                 minute: minute, 
                 second: 0, 
                 nanosecond: 0 
      )! 
    } 

Antwort

0

Um dies zu tun, müssen Sie eine NSTimer verwenden, um das Countdown-Label zu aktualisieren.

Erstellen Sie in Ihrem ViewController eine Variable für den Timer.

var timer = NSTimer() 

ich auch eine temporäre Variable eingerichtet, um die zukünftigen Datum zu halten - Sie keinen Code schreiben habe, so dass ich bin mir nicht sicher, was dein genannt wird. In meinem Code, beziehe ich mich auf sie als futureDate

let futureDate = NSDate().dateByAddingTimeInterval(60*60*2.4) 

Wenn Ihre Anwendung ein Datum auswählt, und Sie wollen, dass der Countdown zu starten, sollten Sie den Timer Zündung einzuleiten, um eine Methode aufzurufen, die das Etikett aktualisiert. In diesem Beispiel nenne ich es updateTimeLeft.

timer = NSTimer.scheduledTimerWithTimeInterval(0.5, target: self, selector: "updateTimeLeft", userInfo: nil, repeats: true) 

Dann müssen wir einfach den Unterschied zwischen jetzt und dem zukünftigen Datum berechnen, wenn die lokale Benachrichtigung ausgelöst wird. Wir machen das in der updateTimeLeft Methode. In meinem Code habe ich eine IBOutlet an die UILabel namens timeLeft.

func updateTimeLeft() 
{ 
    let elapsedTime = futureDate.timeIntervalSinceDate(NSDate()) 
    self.timeLeft.text = NSDateComponentsFormatter().stringFromTimeInterval(elapsedTime) 
} 
+0

Das funktioniert, aber es gibt mindestens zwei grundlegende Probleme mit dieser Lösung: 1.Lokalisierung (Sie können sich nicht darauf verlassen, dass Zeitkomponenten in allen Ländern und Sprachen auf dieselbe Weise formatiert sind). 2. Es gibt Situationen, in denen man sich nicht darauf verlassen kann, dass die Stunde 3600 Sekunden und der Tag 24 Stunden hat (siehe UTC für weitere Informationen). Es ist also vorzuziehen, dass das System es richtig handhabt. – Andriy

+0

Ja, ich habe es bereits aktualisiert, um NSDateComponentsFormatter zu verwenden. – wottle

+0

Nur eine Randnotiz: 'NSTimer' ist keine zuverlässige Möglichkeit, die verbleibende Zeit zu erkennen, da es manchmal aus ist ... – penatheboss

0

Um benutzerfreundliche Saite anzeigen Sie können sich auf NSDateComponentsFormatter beziehen, wenn Ihre App auf iOS 8 und höher ausgerichtet ist.

Außerdem können Sie ein Problem auftreten. UIDatePicker gibt ein NSDate Objekt zurück, das die Sekundenanzahl vom 1. Januar 2001 einkapselt. Auch wenn Sie nur die Zeitkomponente in der Datumsauswahl sehen. Das bedeutet, Sie sollten auf den date Wert von UIDatePicker achten und ihn vielleicht mit NSCalendar API "reparieren".

+0

Ich habe gerade meinen Beitrag aktualisiert vielleicht hilft das. – R3ptor

+0

@ R3ptor Warum müssen Sie eine Erweiterung schreiben? Sie können einfach 'NSDateComponentsFormatter.stringFromDate (startDate: NSDate(), toDate endDate: yourFireDate)' aufrufen und die gewünschte Zeichenfolge für Ihre UI abrufen. – Andriy

+0

Ja, du hast wahrscheinlich recht. Aber könnte mir bei meiner ursprünglichen Frage helfen? Ich verstehe, was du meinst, aber ich bin noch immer ziemlich neu in Swift. Wie genau würde ich das mit der NSCalendar API machen? Und wie würde das im Code aussehen? – R3ptor