0

I want to add a subview (UIButton) in my custom view. However, when I do addSubview() in my created function, it won't add the UIButton, even when I call setNeedsLayout(). I call the addButton() in the ViewController

class PlayingField: UIView {

    var buttons: [UIButton] = []

    func addButton() {
        let button = UIButton()
        addSubview(button)
        buttons.append(button)
        setNeedsLayout()
        layoutIfNeeded()
    }

    override func layoutSubviews() {
        for i in buttons.indices {
            buttons[i].frame = CGRect(x: 50, y: 50, width: 100, height: 100)
            buttons[i].backgroundColor = UIColor.green
        }
    }
}
rmaddy
  • 314,917
  • 42
  • 532
  • 579

2 Answers2

0

Are you sure that you are able to draw your CustomView? Do you see any other components in this view?

Because if you have an xib file bound to this file, then you might need to load nib. You can find an answer for how to do it here: Load UIView from nib

If not, you might have a problem that layoutSubviewswasn't called and that's why you were not adding subview at all.

Yusuf Kamil AK
  • 771
  • 8
  • 17
  • When I add the UIButton directly on layoutSubViews(), it works (it draws all the UIButtons that are in the buttons array), however it only gets called once in the beginning. So when I update the buttons array, it does not update the view. – Drew Mathers Aug 06 '19 at 13:30
  • Then you might consider using `StackView`. If you do so, you can add your buttons easily and well-organised using `addArrangedSubviews` – Yusuf Kamil AK Aug 06 '19 at 13:32
0

Using the original code you posted, here is a complete example:

class CustomView: UIView {
    var buttons: [UIButton] = []

    func addButton() {
        let button = UIButton(frame: CGRect(x: 50, y: 50, width: 100, height: 100))
        buttons.append(button)
        setNeedsLayout()
    }

    override func layoutSubviews() {
        for i in buttons.indices {
            buttons[i].frame = bounds.offsetBy(dx: CGFloat(20), dy: CGFloat(20))
            buttons[i].backgroundColor = UIColor.black
            addSubview(buttons[i])
        }
    }
}

class CustomViewController: UIViewController {

    let cView: CustomView = {
        let v = CustomView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.backgroundColor = .cyan
        return v
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        view.addSubview(cView)

        NSLayoutConstraint.activate([
            cView.widthAnchor.constraint(equalToConstant: 240),
            cView.heightAnchor.constraint(equalToConstant: 120),
            cView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            cView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
            ])

        cView.addButton()
    }

}

Result - cyan rect is the CustomView ... black rect is the button:

enter image description here

As a side note, this works, but using layoutSubviews() to add elements is not a great idea.

DonMag
  • 69,424
  • 5
  • 50
  • 86