How to change the background color of UIStackView?
You can't do this –
UIStackView
is a non-drawing view, meaning thatdrawRect()
is never called and its background color is ignored. If you desperately want a background color, consider placing the stack view inside anotherUIView
and giving that view a background color.
Reference from HERE.
EDIT:
You can add a subView to UIStackView
as mentioned HERE or in this answer (below) and assign a color to it. Check out below extension
for that:
extension UIStackView {
func addBackground(color: UIColor) {
let subView = UIView(frame: bounds)
subView.backgroundColor = color
subView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
insertSubview(subView, at: 0)
}
}
And you can use it like:
stackView.addBackground(color: .red)
UIStackView
is a non-rendering element, and as such, it does not get drawn on the screen. This means that changing backgroundColor
essentially does nothing. If you want to change the background color, just add a UIView
to it as a subview (that is not arranged) like below:
extension UIStackView {
func addBackground(color: UIColor) {
let subview = UIView(frame: bounds)
subview.backgroundColor = color
subview.autoresizingMask = [.flexibleWidth, .flexibleHeight]
insertSubview(subview, at: 0)
}
}
It's worth pointing out that starting with iOS 14, UIStackViews do render background colours. You can either set the background of the UIStackView from the Storyboard with the Background property.
Or in code with:
if #available(iOS 14.0, *) {
stackView.backgroundColor = .green
} else {
// Fallback for older versions of iOS
}
I do it like this:
@IBDesignable
class StackView: UIStackView {
@IBInspectable private var color: UIColor?
override var backgroundColor: UIColor? {
get { return color }
set {
color = newValue
self.setNeedsLayout() // EDIT 2017-02-03 thank you @BruceLiu
}
}
private lazy var backgroundLayer: CAShapeLayer = {
let layer = CAShapeLayer()
self.layer.insertSublayer(layer, at: 0)
return layer
}()
override func layoutSubviews() {
super.layoutSubviews()
backgroundLayer.path = UIBezierPath(rect: self.bounds).cgPath
backgroundLayer.fillColor = self.backgroundColor?.cgColor
}
}
Works like a charm