user12418101
user12418101

Reputation:

How to get uitextfield to countdown from minute and seconds

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()
    }
}

}

Upvotes: 0

Views: 125

Answers (2)

Robin
Robin

Reputation: 303

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()
    }
}

Upvotes: 0

Shehata Gamal
Shehata Gamal

Reputation: 100533

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)"

Upvotes: 1

Related Questions