0

I am creating a custom button and the code for this is below. All the styling elements are working, however my the name and image subviews are not being added. I am sure this is a simple error, but I would appreciate it if someone could help me. Thank you.

class MaterialButton: UIButton {

    let name = UILabel()
    let image = UIImageView()

    override init(frame: CGRect) {
        super.init(frame: frame)
        setupButton()

    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
        super.init(coder: aDecoder)
        setupButton()
    }

    func setupButton() {
        name.textColor = .white
        //        name.font = UIFont(name: "HelveticaNeue-UltraLight",size: 10.0)
        name.textAlignment = .center
        self.layer.cornerRadius = 20
        addSubview(name)
        positionName()

        addSubview(image)
        positionImage()
    }

    func positionName() {
        name.translatesAutoresizingMaskIntoConstraints = false
        name.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: 10).isActive = true
        name.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -10).isActive = true
        name.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 10).isActive = true
        name.heightAnchor.constraint(equalToConstant: self.bounds.height - image.bounds.height - 20).isActive = true
    }
    func positionImage() {
        image.translatesAutoresizingMaskIntoConstraints = false
        image.heightAnchor.constraint(equalToConstant: image.bounds.width).isActive = true
        image.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -10).isActive = true
        image.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 10).isActive = true
        image.topAnchor.constraint(equalTo: self.topAnchor, constant: 10).isActive = true
    }
}

Example of how button is implemented (other button was declared initialized with Material Button earlier in the code)

func setupOtherButton() { // Setting up plastic button
        otherButton.name.text = "Other"
        otherButton.name.textColor = .white
        otherButton.backgroundColor = .gray
        miniSV1.addSubview(otherButton) // Add plastic button to view
        otherButton.addTarget(self, action: #selector(otherButtonTapped), for: .touchUpInside)
    }
Eshan
  • 115
  • 7
  • And how do you use this custom button? i.e what's the code that you are running to use one? – Ahmad F Mar 08 '20 at 01:05
  • I added the code for this in the question – Eshan Mar 08 '20 at 01:14
  • First, remove the `fatalError()` line from `init(coder:)`. Second, the way to debug is to simplify: start by adding just the image, and make it fill the whole bounds. Then change constrains one by one until it's positioned the way you want it. Then do the same with the label. – Yonat Mar 08 '20 at 08:13

1 Answers1

0

Well don't know the exact UI that you are implementing but I did some changes in your code and got the following UI:

enter image description here

So for the button in viewDidLoad :

class ViewController: UIViewController {

    var otherButton = MaterialButton()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        otherButton.frame = CGRect(x: 10, y: 180, width: 140, height: 140)
        otherButton.name.text = "Other"
        otherButton.name.textColor = .white
        otherButton.backgroundColor = .gray
        self.view.addSubview(otherButton)
    }
}

And few changes in the constraints:

class MaterialButton: UIButton {

    let name = UILabel()
    let image = UIImageView()

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

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
        super.init(coder: aDecoder)
        setupButton()
    }

    func setupButton() {
        image.backgroundColor = UIColor.yellow
        addSubview(image)
        positionImage()

        name.textColor = .white
        name.textAlignment = .center
        name.backgroundColor = .blue
        self.layer.cornerRadius = 20
        addSubview(name)
        positionName()
    }

    func positionName() {
        name.translatesAutoresizingMaskIntoConstraints = false
        name.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -10).isActive = true
        name.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -10).isActive = true
        name.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 10).isActive = true
        name.heightAnchor.constraint(equalToConstant: 20).isActive = true
    }

    func positionImage() {
        image.translatesAutoresizingMaskIntoConstraints = false
        image.heightAnchor.constraint(equalToConstant: 50).isActive = true
        image.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -10).isActive = true
        image.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 10).isActive = true
        image.topAnchor.constraint(equalTo: self.topAnchor, constant: 10).isActive = true
    }
}

Check out this URL for better understanding of the constraints programmatically:

Amit
  • 4,837
  • 5
  • 31
  • 46