Difference between drawRect() in custom UIView class and drawing in viewDidLoad()

I have three buttons. One button whose properties are changed by a custom subclass. Another one being an IBOutlet and another one being an instance of UIButton.

Now, why do I need to set masksToBounds/clipsToBounds to true in subclass to change its corner radius but don’t need to mention it in viewDidLoad?

Here is the code for the custom subclass:

class CustomButton: UIButton {

    override func draw(_ rect: CGRect) {
        self.layer.cornerRadius = self.frame.height/2
        self.clipsToBounds = true
    }
}

Here is the code for ViewController:

class ViewController: UIViewController {

    @IBOutlet var iboutletButton: UIButton!

    override func viewDidLoad() {
        super.viewDidLoad()
    
        let someButton = UIButton()
        someButton.frame = CGRect(x: Int(self.view.frame.width/4), y: Int(self.view.frame.height/2), width: 200, height: 50)
        someButton.layer.backgroundColor = UIColor.blue.cgColor
        someButton.setTitle("Instance of UIButton", for: .normal)
        someButton.layer.cornerRadius = someButton.frame.height/2
        self.view.addSubview(someButton)
    
        iboutletButton.layer.cornerRadius = iboutletButton.frame.height/2
    }

}

And here’s the output:

You need to use the UIView class clipsToBounds property in order to make sure that the custom button isn’t drawn over the corner radius. This isn’t necessary for standard ones since they actually behave like that by default and out of the box.

Very well. Now this brings me to my next question - how does shadow work in both the cases?

For the custom button when I try to add shadows, it gets removed because clipsToBounds is set to true, but in case of ViewController it just works fine. How is that happening?

Please share your shadow code when you get a chance. Thank you! :]

Here’s the code for the button using custom class:

class CustomButton: UIButton {

    override func draw(_ rect: CGRect) {
        self.layer.cornerRadius = self.frame.height/2
        self.layer.masksToBounds = true
    
        self.layer.shadowOpacity = 0.7
        self.layer.shadowOffset = CGSize(width: 0, height: 5)
        self.layer.shadowColor = UIColor.black.cgColor
        self.layer.shadowRadius = 3.0
    }

}

Here’s the code for ViewController:

class ViewController: UIViewController {

    @IBOutlet var iboutletButton: UIButton!

    override func viewDidLoad() {
        super.viewDidLoad()
    
        let someButton = UIButton()
        someButton.frame = CGRect(x: Int(self.view.frame.width/4), y: Int(self.view.frame.height/2), width: 200, height: 50)
        someButton.layer.backgroundColor = UIColor.blue.cgColor
        someButton.setTitle("Instance of UIButton", for: .normal)
        someButton.layer.cornerRadius = someButton.frame.height/2
    
        someButton.layer.shadowOpacity = 0.7
        someButton.layer.shadowOffset = CGSize(width: 0, height: 5)
        someButton.layer.shadowColor = UIColor.black.cgColor
        someButton.layer.shadowRadius = 3.0
        self.view.addSubview(someButton)
    
        iboutletButton.layer.cornerRadius = iboutletButton.frame.height/2
        iboutletButton.layer.shadowOpacity = 0.7
        iboutletButton.layer.shadowOffset = CGSize(width: 0, height: 5)
        iboutletButton.layer.shadowColor = UIColor.black.cgColor
        iboutletButton.layer.shadowRadius = 3.0
    }

}

And here’s the output:

Someone help please. :confused:

This topic was automatically closed after 166 days. New replies are no longer allowed.