Search code examples
iosswiftstackview

Swift: Radio button into StackView are not displayed properly


I created a list of radio button in a stackView, but I do not understand why they are displayed wrong, they are not properly aligned

I want all my buttons to be correctly aligned on the left as I can solve this problem thank you! And here is the result in photo:

Here is a part of the code:

var buttons = [UIButton]()
var titles = ["Lasy", "What I've been told", "I'm do into it", "Close the best i can", "Hard core"]


func setupUI() {

    for title in titles {
        // create button
        let button = UIButton(type: .custom)
        button.setTitleColor(.black, for: .normal)
        button.setTitle(title, for: .normal)
        button.setImage(UIImage(named: "uncheck.png")!, for: .normal)

        // if the selected button cannot be reclick again, you can use .Disabled state
        button.setImage(UIImage(named: "check.png")!, for: .selected)
        button.imageEdgeInsets = UIEdgeInsetsMake(0, 0, 0, 35)
        button.addTarget(self, action: #selector(radioButtonAction), for: .touchUpInside)

        buttons.append(button)
    }

    for button in buttons {
        addArrangedSubview(button)
    }

    setupUserChoice()
}

func setupUserChoice(){
    if titles.contains(value) {
        let valueIndex = titles.index(of: value)

        radioButtonAction(sender: buttons[valueIndex!])
    }
}

func setStackView() {
    stackView.translatesAutoresizingMaskIntoConstraints = false
    stackView.axis = .vertical
    stackView.distribution = .fill
    stackView.spacing = 16.0
    stackView.alignment = .leading
}

Solution

  • The problem is with the way you are trying to set the imageEdgeInsets. It is only adjusting the image position, not increasing the size of the button accordingly. For increasing the size of the button, you need to set contentEdgeInsets. But you also need to adjust the title position according to the change in image's position. You can use titleEdgeInsets for that.

    So remove you code button.imageEdgeInsets = UIEdgeInsetsMake(0, 0, 0, 35) and replace it with :-

    let leftPadding_beforeImage: CGFloat = 35
    let gapBetweenImageAndTitle: CGFloat = 8
    let rightPadding_afterTitle: CGFloat = 16
    
    button.imageEdgeInsets = UIEdgeInsetsMake(0, leftPadding_beforeImage, 0, 0)
    button.titleEdgeInsets = UIEdgeInsetsMake(0, (leftPadding_beforeImage+gapBetweenImageAndTitle), 0, -(leftPadding_beforeImage+gapBetweenImageAndTitle))
    button.contentEdgeInsets = UIEdgeInsetsMake(0, 0, 0, (leftPadding_beforeImage+gapBetweenImageAndTitle+rightPadding_afterTitle))
    

    I hope the variable names are self-explanatory. If you want to know more about UIButton edgeInsets, I suggest you reading this fantastic answer.