0

My swift code below can take seconds and countdown from what is placed in the textfield.I want the user to be able to enter 5:30 and have that countdown 330 seconds. Right now for the user to do that I would have to write 330 seconds instead of 5:30.

   import UIKit

   class ViewController: UIViewController {

var enterTime = UITextField()
var lblTime = UILabel()
var startBTN = UIButton()
var timer = Timer()
var counter = 0

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.

    [enterTime,lblTime,startBTN].forEach{
        $0.backgroundColor = .systemRed
        view.addSubview($0)
        $0.translatesAutoresizingMaskIntoConstraints = false
    }

    enterTime.frame = CGRect(x: view.center.x-115, y: view.center.y-200, width: 60, height: 50)
    lblTime.frame = CGRect(x: view.center.x-115, y: view.center.y, width: 60, height: 50)
    startBTN.frame = CGRect(x: view.center.x-115, y: view.center.y+200, width: 60, height: 50)

    startBTN.addTarget(self, action: #selector(startHit), for: .touchDown)

    enterTime.placeholder = String("MM:SS")


}



@objc func startHit() {
    timer.invalidate()
    if let counterText = enterTime.text, let counterValue = Int(counterText) {
        counter = counterValue
        lblTime.text = String(counter)
        timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(timerAction), userInfo: nil, repeats: true)
    }
}

@objc func timerAction() {
    counter -= 1
    lblTime.text = String(counter)
    if ( counter == 0 ) {
        timer.invalidate()
    }
}

}

2 Answers2

1

You can try

let str = "5:30"
let arr = str.components(separatedBy:":")
let fr = Int(arr.first!)!
let la = Int(arr.last!)!
count = fr * 60 + la // 330

To re-format

let lef = count / 60
let rig = count % 60
let res = "\(lef):\(rig)"
Shehata Gamal
  • 98,760
  • 8
  • 65
  • 87
0

You could extract that functionality in a two function like

// Formatting from displayed string to seconds
func convertToSeconds(from timeString: String) -> Int {
    let components = timeString.components(separatedBy: ":")
    if components.count == 2 {
        let minutes = Int(components[0]) ?? 0
        let seconds = Int(components[1]) ?? 0
        return (minutes * 60) + seconds
    } else if components.count == 3 {
        let hours = Int(components[0]) ?? 0
        let minutes = Int(components[1]) ?? 0
        let seconds = Int(components[2]) ?? 0
        return (hours * 60 * 60) + (minutes * 60) + seconds
    } else {
        return 0
    }
}

// Formatting from seconds to displayed string
func convertToTimestring(from seconds: Int) -> String {
    let formatter = DateComponentsFormatter()
    formatter.allowedUnits = [.hour, .minute, .second]
    formatter.unitsStyle = .positional
    let formattedString = formatter.string(from: TimeInterval(seconds))!
    return formattedString
}

And then use it like

let timeSting = "03:30"
let seconds = convertToSeconds(from: timeSting)

Or with hours aswell

let timeSting = "01:03:30"
let seconds = convertToSeconds(from: timeSting)

So your hitStart function could look like this

@objc func startHit() {
    timer.invalidate()
    counter = convertToSeconds(from: enterTime.text)
    timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(timerAction), userInfo: nil, repeats: true)
}

So your timerAction function could look like this

@objc func timerAction() {
    counter -= 1
    lblTime.text = convertToTimestring(from: counter)
    if ( counter == 0 ) {
        timer.invalidate()
    }
}
Robin
  • 303
  • 1
  • 4
  • 16
  • Can you write the it with my code. I am confused on where to insert timeString into my code. Thanks for you help Robin. –  Dec 23 '19 at 00:05
  • This is exactly what I want the only thing is I would like the label on the timer to be converted to min and seconds so right now 6:00 counts down from 360. I would like it to count down 6, 5:59,5:58. etc. Thanks –  Dec 23 '19 at 01:50