UIStackView rounded corners for deployment target 12.3

981 views Asked by At

I can easily create a stackview with rounded corners in iOS 14 by doing:

    stackView.layer.cornerRadius = 10
    stackView.clipsToBounds = true

without doing anything else. But since I want my app to also work on iPhone 6 that can't go beyond iOS 12, the above 2 lines of code don't do anything. I have looked at How can I set the cornerRadius of a UIStackView? and adapted the code to my app, but it still doesn't work. To be clear, I have:

  • Changed my build settings to use a deployment target of iOS 12.3
  • Excluded references to scenes and added window variable (Add iOS 12 support to a new Xcode 11 Project)
  • Tested with iPhone 11 and iphone 6 simulator (both did not show rounded corners)

Here's my code:

import UIKit

class ViewController: UIViewController {
    
    let buttonList = ["Dog", "Cat", "Mouse"]

    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.backgroundColor = .black
        
        let stackView = UIStackView()
        stackView.axis = .vertical
        stackView.distribution = .fillEqually
        stackView.alignment = .fill
        stackView.spacing = 6
        stackView.backgroundColor = .systemPink // this actually works
        view.addSubview(stackView)
        
        stackView.translatesAutoresizingMaskIntoConstraints = false
        stackView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        stackView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
        stackView.widthAnchor.constraint(equalToConstant: 140).isActive = true
        
        // The following is "supposed" to create rounded corners for the stackview
        let subView = UIView(frame: stackView.bounds)
        subView.backgroundColor = .yellow // this ends up showing through instead of the systemPink
        subView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        stackView.insertSubview(subView, at: 0)
        subView.layer.cornerRadius = 10
        subView.layer.masksToBounds = true
        subView.clipsToBounds = true
        
        // Fill the stackview with buttons
        for index in 0..<buttonList.count {
            let button = UIButton()
            button.setTitle(buttonList[index], for: .normal)
            button.backgroundColor = .cyan
            button.setTitleColor(.black, for: .normal)
            button.titleLabel?.font = UIFont.systemFont(ofSize: 14)
            stackView.addArrangedSubview(button)
        }
    }
}

And this is what it looks like (no rounded corners):

Stackview doesn't have rounded corners

So what am I missing? How can I make my stackview appear to have rounded corners for iPhone 6 (iOS 12) and above?

1

There are 1 answers

2
Viktor Gavrilov On BEST ANSWER

You could place your stackView inside another view and set background color/corner radius for this container view:

override func viewDidLoad() {
    super.viewDidLoad()
    
    view.backgroundColor = .black
           
    // The following is "supposed" to create rounded corners for the stackview
    let subView = UIView()
    subView.backgroundColor = .yellow // this ends up showing through instead of the systemPink
    subView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
    subView.layer.cornerRadius = 10
    subView.layer.masksToBounds = true
    subView.clipsToBounds = true
    view.addSubview(subView)
    subView.translatesAutoresizingMaskIntoConstraints = false
                            
    let stackView = UIStackView()
    stackView.axis = .vertical
    stackView.distribution = .fillEqually
    stackView.alignment = .fill
    stackView.spacing = 6
    stackView.backgroundColor = .systemPink // this actually works
    
    subView.addSubview(stackView)
    stackView.translatesAutoresizingMaskIntoConstraints = false
    
    // Fill the stackview with buttons
    for index in 0..<buttonList.count {
        let button = UIButton()
        button.setTitle(buttonList[index], for: .normal)
        button.backgroundColor = .cyan
        button.setTitleColor(.black, for: .normal)
        button.titleLabel?.font = UIFont.systemFont(ofSize: 14)
        stackView.addArrangedSubview(button)
    }
    
    NSLayoutConstraint.activate([
        stackView.trailingAnchor.constraint(equalTo: subView.trailingAnchor),
        stackView.leadingAnchor.constraint(equalTo: subView.leadingAnchor),
        stackView.topAnchor.constraint(equalTo: subView.topAnchor),
        stackView.bottomAnchor.constraint(equalTo: subView.bottomAnchor),
        
        subView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
        subView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
        subView.widthAnchor.constraint(equalToConstant: 140)
    ])
}

As far as I know, it is also better to activate NSLayoutConstraint in a group, not one by one

enter image description here