Siemaszefie
Siemaszefie

Reputation: 53

How to get info which specific button is tapped in UIView in another view

I want to add a countdown option to my application. There are 4 ways to select the countdown time. I made a separate UIView which I named BreakTimeView. I have 4 buttons there. I want to get info in the main viewController when pressing one of them. I want this info to give me a specific number of seconds for the timer to count down. I know that if I made this view from scratch in the main viewController, I could trigger my own action. But I don't know how to do it to pass this number of seconds (Int) if the button is in a separate view. I did something like that, but in my opinion it doesn't look good and the question is how can I do it better / smarter?

class ViewController: UIViewController {

    var value: Int = 0
    var bV = BreakTimeView()
    override func viewDidLoad() {
         super.viewDidLoad()
          
        bV = BreakTimeView(frame: CGRect(x: 0,
                                      y: view.frame.maxY + 50,
                                      width: view.frame.size.width,
                                      height: view.frame.size.width))
        view.addSubview(bV)
        
        let tap = UITapGestureRecognizer(target: self, action: #selector(animate))
        view.addGestureRecognizer(tap)
        
        bV.checkButtonPressed = {
            self.value = 30
            print(self.value)
        }
        bV.checkButtonPressed2 = {
            self.value = 45
            print(self.value)
        }
        bV.checkButtonPressed3 = {
            self.value = 60
            print(self.value)
        }
        bV.checkButtonPressed4 = {
            self.value = 90
            print(self.value)
        }
    }
    

    @objc func animate(){
        UIView.animate(withDuration: 1) {
            self.bV.transform = CGAffineTransform(translationX: 0, y: -self.bV.frame.size.width - 50)
        } completion: { completed in
            print("Ekran wjechał")
        }

    }
    
}
class BreakTimeView: UIView{
    private let title = UILabel()
    
    private let button1 = UIButton()
    private let button2 = UIButton()
    private let button3 = UIButton()
    private let button4 = UIButton()

    private let horizonralStack1 = UIStackView()
    private let horizontalStack2 = UIStackView()
    
    private let verticalStack = UIStackView()
    
    var checkButtonPressed : (() -> ()) = {}
    
    var checkButtonPressed2 : (() -> ()) = {}
    var checkButtonPressed3 : (() -> ()) = {}
    var checkButtonPressed4 : (() -> ()) = {}
    override init(frame: CGRect) {
        super.init(frame: frame)
        layer.cornerRadius = 20
        backgroundColor = .gray
        
        configureTitile()
        configureButtons()
        
        configureHS1()
        configureHS2()
        
        addSubview(verticalStack)
        
        verticalStack.addArrangedSubview(horizonralStack1)
        verticalStack.addArrangedSubview(horizontalStack2)
        verticalStack.axis = .vertical
        verticalStack.distribution = .fillEqually
        verticalStack.spacing = 20
        verticalStack.translatesAutoresizingMaskIntoConstraints = false
        
        verticalStack.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 20).isActive = true
        verticalStack.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -20).isActive = true
        verticalStack.topAnchor.constraint(equalTo: title.bottomAnchor, constant: 20).isActive = true
        verticalStack.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -20).isActive = true
        
        
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private func configureTitile() {
        title.text = "Wybierz czas przerwy"
        title.font = UIFont.systemFont(ofSize: 25)
        title.textAlignment = .center
        title.layer.cornerRadius = 20
        title.layer.masksToBounds = true
        title.backgroundColor = .red
        title.translatesAutoresizingMaskIntoConstraints = false
        
        addSubview(title)
        title.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 40).isActive = true
        title.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -40).isActive = true
        title.topAnchor.constraint(equalTo: self.topAnchor, constant: -40).isActive = true
        title.heightAnchor.constraint(equalToConstant: 80).isActive = true
    }
    private func configureButtons(){
        button1.layer.cornerRadius = 20
        button1.backgroundColor = .red
        button1.setTitle("30s", for: .normal)
        button1.titleLabel?.font = UIFont.systemFont(ofSize: 30)
        button1.addTarget(self, action: #selector(butt1), for: .touchUpInside)
        
        button2.layer.cornerRadius = 20
        button2.backgroundColor = .red
        button2.setTitle("45s", for: .normal)
        button2.titleLabel?.font = UIFont.systemFont(ofSize: 30)
        button2.addTarget(self, action: #selector(butt2), for: .touchUpInside)
        
        button3.layer.cornerRadius = 20
        button3.backgroundColor = .red
        button3.setTitle("60s", for: .normal)
        button3.titleLabel?.font = UIFont.systemFont(ofSize: 30)
        button3.addTarget(self, action: #selector(butt3), for: .touchUpInside)
        
        button4.layer.cornerRadius = 20
        button4.backgroundColor = .red
        button4.setTitle("90s", for: .normal)
        button4.titleLabel?.font = UIFont.systemFont(ofSize: 30)
        button4.addTarget(self, action: #selector(butt4), for: .touchUpInside)
    
    }
    
    @objc private func butt1(){
        checkButtonPressed()

        
    }
    @objc private func butt2(){
        checkButtonPressed2()

        
    }
    @objc private func butt3(){
        checkButtonPressed3()

        
    }
    @objc private func butt4(){
        checkButtonPressed4()

        
    }
    
    fileprivate func configureHS1() {
        horizonralStack1.addArrangedSubview(button1)
        horizonralStack1.addArrangedSubview(button2)
        horizonralStack1.axis = .horizontal
        horizonralStack1.distribution = .fillEqually
        horizonralStack1.spacing = 20

    }
    fileprivate func configureHS2() {
        horizontalStack2.addArrangedSubview(button3)
        horizontalStack2.addArrangedSubview(button4)
        horizontalStack2.axis = .horizontal
        horizontalStack2.distribution = .fillEqually
        horizontalStack2.spacing = 20
    }

Of course, I will not print the number of seconds in the application, but I will pass it to a separate function that supports the timer, but for the purposes of the demo I only have this

Upvotes: 0

Views: 154

Answers (1)

Tarun Tyagi
Tarun Tyagi

Reputation: 10132

Inside BreakTimeView replace these callbacks -

var checkButtonPressed : (() -> ()) = {}
var checkButtonPressed2 : (() -> ()) = {}
var checkButtonPressed3 : (() -> ()) = {}
var checkButtonPressed4 : (() -> ()) = {}

with

var checkButtonPressed : ((_ numberOfSeconds: Int) -> Void) = {}

Now your button actions would look like this.

@objc private func action1() {
    checkButtonPressed(30)
}
@objc private func action2() {
    checkButtonPressed(45)
}
@objc private func action3() {
    checkButtonPressed(60)
}
@objc private func action4() {
    checkButtonPressed(90)
}

At the call site, it would look like this -

bV.checkButtonPressed = { [weak self] (numberOfSeconds) in
    self?.value = numberOfSeconds
    print(numberOfSeconds)
}

Upvotes: 1

Related Questions