addArrangedSubview vs addSubview
Asked Answered
H

1

12

I'm newbie and I've wrote a customView inherited from StackView and I created a button programmatically with few attributes and when I add it to my custom view, I have two problems:

  1. If I use addArrangedSubview(myBtn), my view ignores attributes that I added and fills the whole width. But if I use addSubView(myBtn), It's ok(a blue square in 44x44)
  2. If I use addArrangedSubview(myBtn), addTarget() not works and myBtn is not clickable, but when I use addSubView(myBtn), It works perfectly.

Here is my custom view class:

import UIKit

class RatingControl: UIStackView {

//MARK: Initialization
override init(frame: CGRect) {
    super.init(frame: frame)
    setupButtons()
}

required init(coder: NSCoder) {
    super.init(coder:coder)
    setupButtons()
}

//MARK: Private Methods
private func setupButtons() {

    // Create the button
    let button = UIButton()
    button.backgroundColor = UIColor.blue

    // Add constraints
    button.translatesAutoresizingMaskIntoConstraints = false
    button.heightAnchor.constraint(equalToConstant: 44.0).isActive = true
    button.widthAnchor.constraint(equalToConstant: 44.0).isActive = true

    // Setup the button action
    button.addTarget(self, action: #selector(ratingButtonTapped(_:)), for: .touchUpInside)

    // Add the button to the stack
    addArrangedSubview(button)

}
//MARK: Button Action
@objc func ratingButtonTapped(_ sender: Any) {
    print("Button pressed πŸ‘")
}

}

Here is the preview:

enter image description here enter image description here

What's difference between addSubView() and addArrangedSubview()? why these problems happens?

Heavenly answered 18/3, 2019 at 12:44 Comment(2)
It is working properly. No issue with addArrangedSubview – Plunger
I added images to my question. check it out – Heavenly
S
9

I'm assuming you want to add several buttons horizontally (such as with a typical "stars" rating control).

A UIStackView, as might be guessed from its .addArrangedSubview() method, arranges its subviews, based on its .axis, .alignment, .distribution and .spacing properties, as well as its frame.

So, do some reading about UIStackView and how it can be used. Most likely, you are currently constraining your custom view with:

  • top
  • leading
  • trailing (or width)

So adding your button as an arrangedSubView results in it stretching to the width of the stack view, because that's the default.

Adding it as a subview simply overlays the button on the stack view, instead of allowing the stack view to arrange it, and your stack view likely then has a height of zero -- so the button cannot be tapped.

Try setting only top and leading constraints when you add your custom stack view. That should give you a 44 x 44 button that can be tapped.

As you add more buttons using .addArrangedSubview(), those buttons will be arranged horizontally, which is probably what you want.

Snub answered 18/3, 2019 at 13:15 Comment(4)
thanks @DonMag. check my images that I added to my question recently. in situation I use addView(), it is visible (does not has zero height as you said) but no responds to tap. I'm practicing this tutorial and it uses addArrangedSubView but result is different with mine! – Heavenly
@MahdiMoqadasi - are you laying out your custom RatingControl in Storyboard or via code? – Snub
@MahdiMoqadasi - oh, you're following the Food Tracker tutorial. Notice at the start of Part 4 - "Implement a Custom Control" - your vertical stack view is set to Alignment: Leading... during Part 4 you're instructed to change that to Center. At that point, your custom control should only be the width of the number of "star" buttons + the spacing, and should be centered below the image. If you had the vertical stack view set to Alignment: Fill, that is why your button stretched horizontally instead of using your defined width of 44. – Snub
You're missing a point. Your custom horizontal stackView is embedded in a vertical stack view. Check the Alignment of the vertical stack view, and make sure it is set to Center. If you've added left and right constraints to your custom stack view, you have gone away from that tutorial. – Snub

© 2022 - 2024 β€” McMap. All rights reserved.