Search code examples
swiftuibuttonnstimeinterval

Tap button for bpm code not being executed


I'm trying to create a simple controller that will give you the beats per minute every time the user clicks a button. My code compiles successfully, but the code inside the button action is not being called for some reason. Any ideas to what I am doing wrong?

import Foundation
import UIKit

class taptempo: UIViewController {


    private var timeOutInterval = 5.0
    private var minTaps = 3
    private var taps: [NSDate] = []

    var calculatedbpm = 0

    var timeOut = 5
    var minimumTaps = 3

    @IBOutlet weak var tapnumberlabel: UILabel!
    @IBOutlet weak var tapnumberbutton: UIButton!

    override func viewDidLoad(){
        super.viewDidLoad()

        self.tapnumberlabel.text = "\(calculatedbpm)"

    }

    @IBAction func tapnumberbutaction(_ sender: Any) {

        func addTap() -> Int? {
            let thisTap = NSDate()
            if let lastTap = taps.last {
                if thisTap.timeIntervalSince(lastTap as Date) > timeOutInterval {
                    taps.removeAll()
                }
            }
            taps.append(thisTap)
            guard taps.count >= minTaps else { return nil }
            guard let firstTap = taps.first else { return 0 }
            let avgIntervals = thisTap.timeIntervalSince(firstTap as Date) / Double(taps.count - 1)
            calculatedbpm = Int((60.0 / avgIntervals))
            self.tapnumberlabel.text = "\(calculatedbpm)"
            print(calculatedbpm)
            return calculatedbpm

           // print("func not working")
        }
    }
}

Solution

  • You need to define a function that calculate bmp outside a function body. And in button action just call it and update ui.

    @IBAction func tapnumberbutaction(_ sender: Any) {
        self.tapnumberlabel.text = "\(addTap() ?? 0)" // conditional unwrap of returned value
    }
    
    func addTap() -> Int? {
        let thisTap = NSDate()
        if let lastTap = taps.last {
            if thisTap.timeIntervalSince(lastTap as Date) > timeOutInterval {
                taps.removeAll()
            }
        }
        taps.append(thisTap)
        guard taps.count >= minTaps else { return nil }
        guard let firstTap = taps.first else { return 0 }
        let avgIntervals = thisTap.timeIntervalSince(firstTap as Date) / Double(taps.count - 1)
        calculatedbpm = Int((60.0 / avgIntervals))
        print(calculatedbpm)
        return calculatedbpm
    }