16783


Swift で今の時間から任意の時間までの残り時間を出力してくれるプログラムを書いてます。

現在のコードでは現時刻から一秒ごとに時間が減っていくだけなので、解決策を探してます。

個人的にはcntについての定義付けがなされていないかと考えています。

何卒ご指導願います

[code]

    import UIKit
    
    class ViewController: UIViewController {
    
        var cnt : Int = 0
        var timer : NSTimer!//NSTimerというデフォルト機能から引っ張る
        var myInt:Int = 0
    
        override func viewDidLoad() {
    
            let myDate: NSDate = NSDate()
            let myCalendar: NSCalendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
            let myComponents = myCalendar.components([.Year, .Hour, .Minute, .Second],
                fromDate: myDate) // myDate、すなわちNSDateから要素として引っ張り出してる
    
            timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "onUpdate:", userInfo: nil, repeats: true)//カウントダウンのインターバル
            timer.fire()
    
            var myStr: String = "\(myComponents.hour)"
            myStr += "\(myComponents.minute)"
            myStr += "\(myComponents.second)"
    
            myInt = Int(myStr)! // toInt()がSwift2より無効になったようです。myInt=Str(my components,hour,minute,second)=現時刻
    
        }
    
        func onUpdate(timer : NSTimer){
            cnt += 1//cnt+1=cnt,
            let count = myInt - cnt //残り時間＝現在時刻ー現在時刻に１時間足した時刻
            print(count) // println()は、Swift2よりDeprecatedになりました。
        }
    
    }
    
[/code]


CC BY-SA 3.0
2015-09-19T22:19:53.303
16780
2015-10-16T16:15:31.580
2015-10-16T16:15:31.580
5519
12254
question
ios swift
現在時間から任意の時間までの残り時間を出力するプログラム


**UPDATE** :コメントに合わせて修正。

「バスの時刻表アプリのような」とのことですので、そのようなモチーフにしてみました。

大まかな方法は変わりません。

  * 時刻をインスタンス変数に保持しておき、それを`NSDate`に変換する 
    * `NSCalendar`を用いて`12:00:00`のような文字列から、当日の当該時間の`NSDate`を生成しています
    * この部分は実際的にはインスタンス変数に定数として埋め込むのではなく、ファイルやネットワークからの取得になるのだと思います
    * ここでは簡単のために（名前, 時間）のタプルの配列にしています。配列の`index`を変更するようなUIを作れば、カウントダウン対象の時間を切り替えられます
  * `onUpdate()`のタイミングで毎回`NSDate()`から現在時刻を取得し、対象時間との差分を取る 
    * 開始時間からの差分は`timeIntervalSinceDate()`メソッドで取得できます
    * 取得できるのは秒数なので、ここでは除算と剰余で時分秒にしています（算数の問題なので割愛）

出力例

> 午後 6時発までの時間は 03:58:46

* * *

**コード例**

[code]

    class ViewController: UIViewController {
    
        /** カウントダウンしたい時刻の配列 */
        private var targetDates : [(name: String, timeString: String)] = [
            ("午前11時発" , "11:15:00"),
            ("午後 3時発" , "15:30:00"),
            ("午後 6時発" , "18:45:00")
        ]
    
        /** タイマー */
        private var timer :NSTimer!
        /** カウントダウンの対象 */
        private var target :(name: String, time: NSDate)?
    
        override func viewDidLoad() {
    
            // 対象とする日付をセット
            let index = 2
            if let date = dateFromString(targetDates[index].timeString) {
                self.target = (targetDates[index].name, date)
            }
    
            // インターバル1秒でタイマーを生成
            self.timer = NSTimer.scheduledTimerWithTimeInterval(1,
                target: self,
                selector: "onUpdate:",
                userInfo: nil,
                repeats: true)
            self.timer.fire()
        }
    
        /**
         * "HH:mm:ss"を日付型に変換
         */
        func dateFromString(dateString :String) -> NSDate? {
            let calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
            calendar.locale = NSLocale(localeIdentifier: "en_US_POSIX")
            calendar.timeZone = NSTimeZone(abbreviation: "JST")!
    
            let begin = dateString.startIndex
            guard let hour = Int(dateString.substringWithRange(begin..<advance(begin, 2))),
                let minute = Int(dateString.substringWithRange(advance(begin, 3)..<advance(begin, 5))),
                let second = Int(dateString.substringWithRange(advance(begin, 6)..<advance(begin, 8))) else{
                    return nil
            }
    
            return calendar.dateBySettingHour(hour, minute: minute, second: second, ofDate: NSDate(), options: [])
        }
    
        func onUpdate(timer : NSTimer) {
            guard self.target != nil else {
                timer.invalidate()
                return
            }
    
            var remain = Int(self.target!.time.timeIntervalSinceDate(NSDate()))
            if remain < 0 {
                timer.invalidate()
                return
            }
            // 残り時間を(HH:)mm:ddで出力
            print(self.target!.name + "までの時間は ", appendNewline: false)
            if (remain >= 3600) {
                print(String(format: "%02d", arguments: [remain/3600]) + ":", appendNewline: false)
                remain %= 3600
            }
            print(String(format: "%02d:%02d", arguments: [remain/60, remain%60]))
        }
    }
    
[/code]


CC BY-SA 3.0
2015-09-20T01:48:46.287
16783
2015-09-20T09:45:04.240
2015-09-20T09:45:04.240
5337
5337
16780
answer