viewdidroad問題解決?

環境

  • swift : 4.2.1
  • Xcode : 10.1

TimeView.swift

source

import UIKit

var flag = true // viewdidroadで二回関数を呼び出さないようにする

class TimeView : UIViewController {
    
    var timer = Timer()
    var count_sec: Int! = nil
    var count_min: Int! = nil
    var count_hour: Int! = nil
    var pause_time_sec: Int! = nil
    var pause_time_min: Int! = nil
    var pause_time_hour: Int! = nil
    
    // FIXME: rename
    var userDefauls_exp = UserDefaults.standard // 設定保存用
    
    @IBOutlet weak var timeViewSec: UILabel!
    @IBOutlet weak var timeViewMin: UILabel!
    @IBOutlet weak var timeViewHour: UILabel!
    @IBOutlet weak var levelView: UILabel!
    
    override func viewWillAppear(_ animated: Bool) {
        // TODO: level:1からじゃない? 1にした場合,dxの修正?
        // ディクショナリ形式で初期値を指定できる
        userDefauls_exp.register(defaults: ["exp" : 0,
                                            "dx" : 0,
                                            "level" : 0]
                                )
        
        self.timeViewHour.text = String(self.count_hour)
        self.timeViewMin.text = String(self.count_min)
        self.timeViewSec.text = String(self.count_sec)
        
        // データ読み込み
        let read_level = userDefauls_exp.integer(forKey: "level")
        self.levelView.text = "Level : " + "\(read_level)"
    }
    
    override func viewDidLoad() {
        // FIXME: 意図した動作ではあるが、まだ2回呼ばれてる -
        super.viewDidLoad()
        
        if (flag == true) {
            flag = false
            timer = Timer.scheduledTimer(timeInterval: 1.0,
                                         target:   self,
                                         selector: #selector(debug),
                                         userInfo: nil,
                                         repeats:  true)
        }
        print("viewdidload")
    }
    
    
    @objc func debug() -> Void {
        // FIXME: rename
        // FIXME: もっとスマート記述がある
        // TODO: 0h 0m 0sec の時の処理 -
        
        if (self.count_sec == 0) {
            self.count_sec = 59
            timeViewSec.text = String(self.count_sec)
            
            if (self.count_min == 0) {
                self.count_min = 59
                timeViewMin.text = String(self.count_min)
                
                if (self.count_hour == 0){
                    self.count_hour = 0
                    timeViewHour.text = String(self.count_hour)
                }
                else {
                    self.count_hour -= 1
                    timeViewHour.text = String(self.count_hour)
                }
            }
            else {
                self.count_min -= 1
                timeViewMin.text = String(self.count_min)
            }
        }
        else {
            self.count_sec -= 1
            timeViewSec.text = String(self.count_sec)
        }
        
        // debug
        print("\(self.count_sec ?? 00000) sec")
        
        // 経験値get
        get_exp()
        
    }
    
    /// 経験値追加:経験値に応じてLevelが上がる
    func get_exp() {
        
        // TODO: 毎回、値を読み込むのは良くなさそう? -
        // 読み込み
        var exp = userDefauls_exp.integer(forKey: "exp")
        var level = userDefauls_exp.integer(forKey: "level")
        var dx = userDefauls_exp.integer(forKey: "dx")
        
        // exp up!!
        exp += 1

        // 次のLevelまでに必要なexp
        dx = (2*level+1)    // *3600
        
        // 必要expに到達すると Level up
        if (exp == dx) {
            level += 1
            self.levelView.text = "Level : " + String(level)
            exp = 0
        }
        
        // save
        self.userDefauls_exp.set(exp, forKey: "exp")
        self.userDefauls_exp.set(level, forKey: "level")
        self.userDefauls_exp.set(level, forKey: "dx")
        self.userDefauls_exp.synchronize()
        // save
        
    }
    
    /// キャンセル
    @IBAction func cancell_Time(_ sender: UIButton) {
        timer.invalidate() // timer破棄
        flag = true
        
        // 読み込み
        let exp = userDefauls_exp.integer(forKey: "exp")
        let level = userDefauls_exp.integer(forKey: "level")
        let dx = userDefauls_exp.integer(forKey: "dx")
        
        // save
        self.userDefauls_exp.set(exp, forKey: "exp")
        self.userDefauls_exp.set(level, forKey: "level")
        self.userDefauls_exp.set(dx, forKey: "dx")
        self.userDefauls_exp.synchronize()
        // save

        // debug
        print("cancell \(timer.isValid)")
        
    }
    
    /// 一時停止 再開
    @IBAction func Stop_and_Start_button(_ sender: UIButton) {
        // FIXME: 正確な残り時間で再開させる -
        // 停止
        if ("一時停止" == sender.currentTitle!){
            self.pause_time_sec = self.count_sec
            self.pause_time_min = self.count_min
            self.pause_time_hour = self.count_hour
            timer.invalidate() // timer破棄
            sender.setTitle("再開", for: .normal)
            
            // debug
            print("button \(timer.isValid)")
            
        }
        /// 再開
        else {
            self.timeViewSec.text = String(self.pause_time_sec)
            self.timeViewMin.text = String(self.pause_time_min)
            self.timeViewHour.text = String(self.pause_time_hour)
            timer = Timer.scheduledTimer(timeInterval: 1.0,
                                              target:   self,
                                              selector: #selector(debug),
                                              userInfo: nil,
                                              repeats:  true)
            sender.setTitle("一時停止", for: .normal)
            
            // debug
            print(timer.isValid)
        
        }
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

}

覚えたこと

  • userDefaultで値を保存できる(.registerで初期化)
  • ?? : nil結合演算子(nilでないならその値を、nilの場合はデフォルト値)
  • ///でdocコメント
  • 特殊タグ(// TODO: -, ...etc)

これからやること

  • 特殊タグの処理

思ったこと

  • 我ながら吐き気のするコード

終わりに

個人用とはいえ大分コードが増えてきたので、そろそろgitにあげよう...
なぜかgitに苦手意識があって避けていたが、そろそろ決着をつけよう