Sahil Manchanda
Sahil Manchanda

Reputation: 10012

Switch allowing two same case?

TestView:

class TestView: UIView{

    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        commonInit()
    }

    func commonInit(){
        addSubview(stackView)
        setConstraints()
    }
    func setConstraints() {
        let constrains = [
            stackView.topAnchor.constraint(equalTo: topAnchor),
            stackView.leadingAnchor.constraint(equalTo: leadingAnchor),
            stackView.bottomAnchor.constraint(equalTo: bottomAnchor),
            stackView.trailingAnchor.constraint(equalTo: trailingAnchor)
        ]

        NSLayoutConstraint.activate(constrains)

    }

    public let accept: UIButton = {
        let v = UIButton()
        v.backgroundColor = .blue
        v.setTitle("Hello", for: .normal)
        v.setTitleColor(.white, for: .normal)
        v.setTitleColor(UIColor.white.withAlphaComponent(0.5), for: [.highlighted,.selected])
        return v
    }()


    public let deny: UIButton = {
        let v = UIButton()
        v.backgroundColor = .red
        v.setTitle("Deny", for: .normal)
        v.setTitleColor(.white, for: .normal)
        v.setTitleColor(UIColor.white.withAlphaComponent(0.5), for: [.highlighted,.selected])
        return v
    }()

    public lazy var stackView: UIStackView = {
        let v = UIStackView(arrangedSubviews: [accept,deny])
        v.alignment = .fill
        v.axis = .vertical
        v.spacing = 8
        v.distribution = .fillEqually
        v.translatesAutoresizingMaskIntoConstraints = false
        return v
    }()
}

TestViewController

class TestViewController: UIViewController{
    var myView: TestView{return view as! TestView}
    unowned var accept: UIButton {return myView.accept}
    unowned var deny: UIButton {return myView.deny}
    override func loadView() {
        view = TestView()
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        accept.addTarget(self, action: #selector(didSelect), for: .touchUpInside)
        deny.addTarget(self, action: #selector(didSelect), for: .touchUpInside)
    }

    @objc func didSelect(_ sender: UIButton){
        switch sender{
        case accept:
            print("Accept button clicked")
        case deny:
            print("Deny button clicked")
        case accept:
            print("Accept button case again")
        default:
            break
        }
    }
}

The above code is compiling fine in Xcode 10.2.1 Look at the didSelect method. It has a switch block with two same case. Just curious isn't it supposed to thorw compile time error. The program ran successfully without any runtime error also. When i click on accept button, the first case gets executed.

Question: Why there is no compile-time/runtime error in this code?

output:

result

Upvotes: 1

Views: 76

Answers (2)

Abdo
Abdo

Reputation: 352

A better approach to overcome this, you can use button.tag property and in that case you will be able to switch over them correctly.

Just like this one does.

Upvotes: 0

Zaphod
Zaphod

Reputation: 7250

The type of sender being UIButton, the compiler cannot check as it does for enum types.

As the switch works exactly like if/else if statements, it executes only the first one.

It's equivalent to:

if sender == accept {
    print("Accept button clicked")
}
else if sender == deny {
    print("Deny button clicked")
}
else if sender == accept {
    print("Accept button case again")
}
else {
    break
}

Upvotes: 2

Related Questions