第十二天:SwiftStopWatch
参考链接:https://github.com/soapyigu/Swift-30-Projects
1 import UIKit 2 3 class Stopwatch: NSObject { 4 var counter: Double 5 var timer: Timer 6 7 override init() { 8 counter = 0.0 9 timer = Timer() 10 } 11 }
1 import UIKit 2 3 class ViewController: UIViewController, UITableViewDelegate { 4 5 // MARK: - Variables 6 fileprivate let mainStopwatch: Stopwatch = Stopwatch() 7 fileprivate let lapStopwatch: Stopwatch = Stopwatch() 8 fileprivate var isPlay: Bool = false 9 fileprivate var laps: [String] = [] 10 11 // MARK: - UI components 12 @IBOutlet weak var timerLabel: UILabel! 13 @IBOutlet weak var lapTimerLabel: UILabel! 14 @IBOutlet weak var playPauseButton: UIButton! 15 @IBOutlet weak var lapRestButton: UIButton! 16 @IBOutlet weak var lapsTableView: UITableView! 17 18 // MARK: - Life Cycle 19 override func viewDidLoad() { 20 super.viewDidLoad() 21 // Do any additional setup after loading the view, typically from a nib. 22 23 let initCircleButton: (UIButton) -> Void = { button in 24 button.layer.cornerRadius = 0.5 * button.bounds.size.width 25 button.backgroundColor = UIColor.white 26 } 27 28 initCircleButton(playPauseButton) 29 initCircleButton(lapRestButton) 30 31 lapRestButton.isEnabled = false 32 33 lapsTableView.delegate = self 34 lapsTableView.dataSource = self 35 } 36 37 // MARK: - UI Settings 38 override var shouldAutorotate: Bool { 39 return false 40 } 41 42 override var preferredStatusBarStyle: UIStatusBarStyle { 43 return UIStatusBarStyle.lightContent 44 } 45 46 override var supportedInterfaceOrientations: UIInterfaceOrientationMask { 47 return UIInterfaceOrientationMask.portrait 48 } 49 50 // MARK: - Actions 51 @IBAction func playPauseTimer(_ sender: AnyObject) { 52 lapRestButton.isEnabled = true 53 54 changeButton(lapRestButton, title: "Lap", titleColor: UIColor.black) 55 56 if !isPlay { 57 unowned let weakSelf = self 58 59 mainStopwatch.timer = Timer.scheduledTimer(timeInterval: 0.035, target: weakSelf, selector: Selector.updateMainTimer, userInfo: nil, repeats: true) 60 lapStopwatch.timer = Timer.scheduledTimer(timeInterval: 0.035, target: weakSelf, selector: Selector.updateLapTimer, userInfo: nil, repeats: true) 61 62 RunLoop.current.add(mainStopwatch.timer, forMode: .commonModes) 63 RunLoop.current.add(lapStopwatch.timer, forMode: .commonModes) 64 65 isPlay = true 66 changeButton(playPauseButton, title: "Stop", titleColor: UIColor.red) 67 } else { 68 mainStopwatch.timer.invalidate() 69 lapStopwatch.timer.invalidate() 70 isPlay = false 71 changeButton(playPauseButton, title: "Start", titleColor: UIColor.green) 72 changeButton(lapRestButton, title: "Reset", titleColor: UIColor.black) 73 } 74 } 75 76 @IBAction func lapResetTimer(_ sender: AnyObject) { 77 if !isPlay { 78 resetMainTimer() 79 resetLapTimer() 80 changeButton(lapRestButton, title: "Lap", titleColor: UIColor.lightGray) 81 lapRestButton.isEnabled = false 82 } else { 83 if let timerLabelText = timerLabel.text { 84 laps.append(timerLabelText) 85 } 86 lapsTableView.reloadData() 87 resetLapTimer() 88 unowned let weakSelf = self 89 lapStopwatch.timer = Timer.scheduledTimer(timeInterval: 0.035, target: weakSelf, selector: Selector.updateLapTimer, userInfo: nil, repeats: true) 90 RunLoop.current.add(lapStopwatch.timer, forMode: .commonModes) 91 } 92 } 93 94 override func didReceiveMemoryWarning() { 95 super.didReceiveMemoryWarning() 96 // Dispose of any resources that can be recreated. 97 } 98 99 // MARK: - Private Helpers 100 fileprivate func changeButton(_ button: UIButton, title: String, titleColor: UIColor) { 101 button.setTitle(title, for: .normal) 102 button.setTitleColor(titleColor, for: .normal) 103 } 104 105 fileprivate func resetMainTimer() { 106 resetTimer(mainStopwatch, label: timerLabel) 107 laps.removeAll() 108 lapsTableView.reloadData() 109 } 110 111 fileprivate func resetLapTimer() { 112 resetTimer(lapStopwatch, label: lapTimerLabel) 113 } 114 115 fileprivate func resetTimer(_ stopwatch: Stopwatch, label: UILabel) { 116 stopwatch.timer.invalidate() 117 stopwatch.counter = 0.0 118 label.text = "00:00:00" 119 } 120 121 @objc func updateMainTimer() { 122 updateTimer(mainStopwatch, label: timerLabel) 123 } 124 125 @objc func updateLapTimer() { 126 updateTimer(lapStopwatch, label: lapTimerLabel) 127 } 128 129 func updateTimer(_ stopwatch: Stopwatch, label: UILabel) { 130 stopwatch.counter = stopwatch.counter + 0.035 131 132 var minutes: String = "\((Int)(stopwatch.counter / 60))" 133 if (Int)(stopwatch.counter / 60) < 10 { 134 minutes = "0\((Int)(stopwatch.counter / 60))" 135 } 136 137 var seconds: String = String(format: "%.2f", (stopwatch.counter.truncatingRemainder(dividingBy: 60))) 138 if stopwatch.counter.truncatingRemainder(dividingBy: 60) < 10 { 139 seconds = "0" + seconds 140 } 141 142 label.text = minutes + ":" + seconds 143 } 144 } 145 146 // MARK: - UITableViewDataSource 147 extension ViewController: UITableViewDataSource { 148 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 149 return laps.count 150 } 151 152 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 153 let identifier: String = "lapCell" 154 let cell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: identifier, for: indexPath) 155 156 if let labelNum = cell.viewWithTag(11) as? UILabel { 157 labelNum.text = "Lap \(laps.count - (indexPath as NSIndexPath).row)" 158 } 159 160 if let labelTimer = cell.viewWithTag(12) as? UILabel { 161 labelTimer.text = laps[laps.count - (indexPath as NSIndexPath).row - 1] 162 } 163 164 return cell 165 } 166 } 167 168 // MARK: - Extension 169 fileprivate extension Selector { 170 static let updateMainTimer = #selector(ViewController.updateMainTimer) 171 static let updateLapTimer = #selector(ViewController.updateLapTimer) 172 }
怎么样成为程序员,学习和实践,日积月累...