K1llarney
K1llarney

Reputation: 93

Swift 3 - Programmatically build a button with an image and label

I am currently trying to build an interface (programmatically) with 5 x buttons, containing an image and a label.

I have done this successfully for ONE button using a UIStackView (holding the UIButton and a UIlabel).

I have two questions for this forum…

  1. A UIButton can be built to display a title OR an image, can it have both?
  2. Can a ‘for in’ loop be used to generate 5 x individual buttons? i.e: a way to re-use code instead of typing out code for 5 x buttons, 5 x labels, 5 x stack views.

My working UIStackView button code is as follows:

    // Button
    let btnSettings = UIButton()
//  btnSettings.setTitle("Settings", for: .normal)
    btnSettings.setImage(#imageLiteral(resourceName: "star-in-circle"), for: .normal)
    btnSettings.heightAnchor.constraint(equalToConstant: 100.0).isActive = true
    btnSettings.widthAnchor.constraint(equalToConstant: 100.0).isActive = true
    btnSettings.contentMode = .scaleAspectFit
    btnSettings.addTarget(self, action: #selector(openSettings), for: .touchUpInside)
    btnSettings.translatesAutoresizingMaskIntoConstraints = false

    // Text Label
    let textLabel = UILabel()
    textLabel.backgroundColor = UIColor.clear
    textLabel.widthAnchor.constraint(equalToConstant: 100.0).isActive = true
    textLabel.heightAnchor.constraint(equalToConstant: 20.0).isActive = true
    textLabel.font = UIFont.boldSystemFont(ofSize: 18)
    textLabel.text = "Settings"
    textLabel.textAlignment = .center

    // Stack View
    let stackView = UIStackView()
    stackView.axis = UILayoutConstraintAxis.vertical
    stackView.distribution = UIStackViewDistribution.equalSpacing
    stackView.alignment = UIStackViewAlignment.center
    stackView.spacing = 1.0

    stackView.addArrangedSubview(btnSettings)
    stackView.addArrangedSubview(textLabel)
    stackView.translatesAutoresizingMaskIntoConstraints = false

    self.view.addSubview(stackView)

    // Constraints
    stackView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
    stackView.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true

Update / Solved Question 1

I needed to use the button.setBackgroundImage() in order for the button title to show up with the image.

btnSettings.setBackgroundImage(#imageLiteral(resourceName: "star-in-circle"), for: .normal)
btnSettings.setTitle("Button Title", for: .normal)
btnSettings.backgroundColor = UIColor.white

Upvotes: 0

Views: 3414

Answers (1)

Michał Kwiecień
Michał Kwiecień

Reputation: 2874

  1. Of course, UIButton can have both an image or/and text. You can use:

    button.setImage(image: UIImage?, for: UIControlState)
    button.setTitle(title: String?, for: UIControlState)
    
  2. Create a function that will return UIButton and do something like that:

    let button = generateButton()
    stackView.addArrangedSubview(button)
    

Upvotes: 2

Related Questions