如何更改 UIStackView 的背景颜色?
How to change the background color of UIStackView?
我尝试在 Storyboard inspector 中将 UIStackView
背景从透明色更改为白色,但是在模拟时,堆栈视图的背景色仍然是透明色。
如何更改 UIStackView
的背景颜色?
You can't do this – UIStackView
is a non-drawing view, meaning that
drawRect()
is never called and its background color is ignored. If you
desperately want a background color, consider placing the stack view
inside another UIView
and giving that view a background color.
参考自HERE。
编辑:
您可以向 UIStackView
添加子视图,如前所述 HERE or in 并为其指定颜色。查看下面 extension
的内容:
extension UIStackView {
func addBackground(color: UIColor) {
let subView = UIView(frame: bounds)
subView.backgroundColor = color
subView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
insertSubview(subView, at: 0)
}
}
您可以像这样使用它:
stackView.addBackground(color: .red)
我是这样做的:
@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
}
}
很有魅力
在iOS10中,@Arbitur的回答在设置颜色后需要一个setNeedsLayout。这是需要的更改:
override var backgroundColor: UIColor? {
get { return color }
set {
color = newValue
setNeedsLayout()
}
}
也许最简单、更易读且更简单的方法是将 UIStackView
嵌入到 UIView
中并为视图设置背景颜色。
并且不要忘记正确配置这两个视图之间的自动布局约束……;-)
TL;DR:官方方法是使用 addSubview:
方法将空视图添加到堆栈视图中,然后设置添加的视图背景。
说明:UIStackView是一个特殊的UIView子类,只做布局不做绘图。它的许多属性将无法正常工作。由于 UIStackView 只会布置其排列的子视图,这意味着您可以简单地使用 addSubview:
方法向其添加 UIView ,设置其约束和背景颜色。这是实现你想要的官方方式quoted from WWDC session
Pitiphong 是正确的,要获得具有背景颜色的堆栈视图,请执行以下操作...
let bg = UIView(frame: stackView.bounds)
bg.autoresizingMask = [.flexibleWidth, .flexibleHeight]
bg.backgroundColor = UIColor.red
stackView.insertSubview(bg, at: 0)
这将为您提供一个堆栈视图,其内容将放置在红色背景上。
要向堆栈视图添加填充以使内容不与边缘齐平,请在代码或情节提要中添加以下内容...
stackView.isLayoutMarginsRelativeArrangement = true
stackView.layoutMargins = UIEdgeInsets(top: 8, left: 8, bottom: 8, right: 8)
UIStackView *stackView;
UIView *stackBkg = [[UIView alloc] initWithFrame:CGRectZero];
stackBkg.backgroundColor = [UIColor redColor];
[self.view insertSubview:stackBkg belowSubview:stackView];
stackBkg.translatesAutoresizingMaskIntoConstraints = NO;
[[stackBkg.topAnchor constraintEqualToAnchor:stackView.topAnchor] setActive:YES];
[[stackBkg.bottomAnchor constraintEqualToAnchor:stackView.bottomAnchor] setActive:YES];
[[stackBkg.leftAnchor constraintEqualToAnchor:stackView.leftAnchor] setActive:YES];
[[stackBkg.rightAnchor constraintEqualToAnchor:stackView.rightAnchor] setActive:YES];
这适用于 Swift 3 和 iOS 10:
let stackView = UIStackView()
let subView = UIView()
subView.backgroundColor = .red
subView.translatesAutoresizingMaskIntoConstraints = false
stackView.addSubview(subView) // Important: addSubview() not addArrangedSubview()
// use whatever constraint method you like to
// constrain subView to the size of stackView.
subView.topAnchor.constraint(equalTo: stackView.topAnchor).isActive = true
subView.bottomAnchor.constraint(equalTo: stackView.bottomAnchor).isActive = true
subView.leftAnchor.constraint(equalTo: stackView.leftAnchor).isActive = true
subView.rightAnchor.constraint(equalTo: stackView.rightAnchor).isActive = true
// now add your arranged subViews...
stackView.addArrangedSubview(button1)
stackView.addArrangedSubview(button2)
你可以这样做:
stackView.backgroundColor = UIColor.blue
通过提供扩展来覆盖 backgroundColor
:
extension UIStackView {
override open var backgroundColor: UIColor? {
get {
return super.backgroundColor
}
set {
super.backgroundColor = newValue
let tag = -9999
for view in subviews where view.tag == tag {
view.removeFromSuperview()
}
let subView = UIView()
subView.tag = tag
subView.backgroundColor = newValue
subView.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(subView)
subView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
subView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
subView.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true
subView.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
}
}
}
这里是添加堆栈视图背景颜色的简要概述。
class RevealViewController: UIViewController {
@IBOutlet private weak var rootStackView: UIStackView!
创建带圆角的背景视图
private lazy var backgroundView: UIView = {
let view = UIView()
view.backgroundColor = .purple
view.layer.cornerRadius = 10.0
return view
}()
为了让它显示为背景,我们将它添加到索引 0 处的根堆栈视图的子视图数组中。这将它放在堆栈视图的排列视图后面。
private func pinBackground(_ view: UIView, to stackView: UIStackView) {
view.translatesAutoresizingMaskIntoConstraints = false
stackView.insertSubview(view, at: 0)
view.pin(to: stackView)
}
通过在 UIView 上使用一个小扩展,添加约束以将 backgroundView 固定到堆栈视图的边缘。
public extension UIView {
public func pin(to view: UIView) {
NSLayoutConstraint.activate([
leadingAnchor.constraint(equalTo: view.leadingAnchor),
trailingAnchor.constraint(equalTo: view.trailingAnchor),
topAnchor.constraint(equalTo: view.topAnchor),
bottomAnchor.constraint(equalTo: view.bottomAnchor)
])
}
}
从 viewDidLoad
调用 pinBackground
override func viewDidLoad() {
super.viewDidLoad()
pinBackground(backgroundView, to: rootStackView)
}
参考自:HERE
UIStackView
是非渲染元素,因此不会在屏幕上绘制。这意味着更改 backgroundColor
基本上什么都不做。如果你想改变背景颜色,只需添加一个 UIView
作为子视图(未排列),如下所示:
extension UIStackView {
func addBackground(color: UIColor) {
let subview = UIView(frame: bounds)
subview.backgroundColor = color
subview.autoresizingMask = [.flexibleWidth, .flexibleHeight]
insertSubview(subview, at: 0)
}
}
Xamarin,C# 版本:
var stackView = new UIStackView { Axis = UILayoutConstraintAxis.Vertical };
UIView bg = new UIView(stackView.Bounds);
bg.AutoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight;
bg.BackgroundColor = UIColor.White;
stackView.AddSubview(bg);
子class UIStackView
class CustomStackView : UIStackView {
private var _bkgColor: UIColor?
override public var backgroundColor: UIColor? {
get { return _bkgColor }
set {
_bkgColor = newValue
setNeedsLayout()
}
}
private lazy var backgroundLayer: CAShapeLayer = {
let layer = CAShapeLayer()
self.layer.insertSublayer(layer, at: 0)
return layer
}()
override public func layoutSubviews() {
super.layoutSubviews()
backgroundLayer.path = UIBezierPath(rect: self.bounds).cgPath
backgroundLayer.fillColor = self.backgroundColor?.cgColor
}
}
然后在你的class
yourStackView.backgroundColor = UIColor.lightGray
你可以在 StackView 中插入一个子层,它对我有用:
@interface StackView ()
@property (nonatomic, strong, nonnull) CALayer *ly;
@end
@implementation StackView
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
_ly = [CALayer new];
[self.layer addSublayer:_ly];
}
return self;
}
- (void)setBackgroundColor:(UIColor *)backgroundColor {
[super setBackgroundColor:backgroundColor];
self.ly.backgroundColor = backgroundColor.CGColor;
}
- (void)layoutSubviews {
self.ly.frame = self.bounds;
[super layoutSubviews];
}
@end
您可以对 UIStackView
做一个小扩展
extension UIStackView {
func setBackgroundColor(_ color: UIColor) {
let backgroundView = UIView(frame: .zero)
backgroundView.backgroundColor = color
backgroundView.translatesAutoresizingMaskIntoConstraints = false
self.insertSubview(backgroundView, at: 0)
NSLayoutConstraint.activate([
backgroundView.topAnchor.constraint(equalTo: self.topAnchor),
backgroundView.leadingAnchor.constraint(equalTo: self.leadingAnchor),
backgroundView.bottomAnchor.constraint(equalTo: self.bottomAnchor),
backgroundView.trailingAnchor.constraint(equalTo: self.trailingAnchor)
])
}
}
用法:
yourStackView.setBackgroundColor(.black)
我对 UI 组件的子类化有点怀疑。这就是我的使用方式,
struct CustomAttributeNames{
static var _backgroundView = "_backgroundView"
}
extension UIStackView{
var backgroundView:UIView {
get {
if let view = objc_getAssociatedObject(self, &CustomAttributeNames._backgroundView) as? UIView {
return view
}
//Create and add
let view = UIView(frame: .zero)
view.translatesAutoresizingMaskIntoConstraints = false
insertSubview(view, at: 0)
NSLayoutConstraint.activate([
view.topAnchor.constraint(equalTo: self.topAnchor),
view.leadingAnchor.constraint(equalTo: self.leadingAnchor),
view.bottomAnchor.constraint(equalTo: self.bottomAnchor),
view.trailingAnchor.constraint(equalTo: self.trailingAnchor)
])
objc_setAssociatedObject(self,
&CustomAttributeNames._backgroundView,
view,
objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
return view
}
}
}
这是用法,
stackView.backgroundView.backgroundColor = .white
stackView.backgroundView.layer.borderWidth = 2.0
stackView.backgroundView.layer.borderColor = UIColor.red.cgColor
stackView.backgroundView.layer.cornerRadius = 4.0
注意:使用这种方法,如果要设置边框,则必须在 stackView 上设置 layoutMargins
以便边框可见。
您无法将背景添加到堆栈视图。
但是您可以做的是在视图中添加堆栈视图,然后设置视图背景,这将完成工作。
*它不会中断堆栈视图的流程。
希望这会有所帮助。
我们可以像这样自定义 class StackView
:
class StackView: UIStackView {
lazy var backgroundView: UIView = {
let otherView = UIView()
addPinedSubview(otherView)
return otherView
}()
}
extension UIView {
func addPinedSubview(_ otherView: UIView) {
addSubview(otherView)
otherView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
otherView.trailingAnchor.constraint(equalTo: trailingAnchor),
otherView.topAnchor.constraint(equalTo: topAnchor),
otherView.heightAnchor.constraint(equalTo: heightAnchor),
otherView.widthAnchor.constraint(equalTo: widthAnchor),
])
}
}
并且可以这样使用:
let stackView = StackView()
stackView.backgroundView.backgroundColor = UIColor.lightGray
这比其他人建议的添加扩展函数 func addBackground(color: UIColor)
稍微好一些。背景视图是惰性的,因此在您实际调用 stackView.backgroundView.backgroundColor = ...
之前不会创建它。并且 setting/changing 背景颜色多次不会导致在堆栈视图中插入多个子视图。
如果您想从设计器本身进行控制,请将此扩展添加到堆栈视图
@IBInspectable var customBackgroundColor: UIColor?{
get{
return backgroundColor
}
set{
backgroundColor = newValue
let subview = UIView(frame: bounds)
subview.backgroundColor = newValue
subview.autoresizingMask = [.flexibleWidth, .flexibleHeight]
insertSubview(subview, at: 0)
}
}
值得指出的是,从 iOS 14 开始,UIStackViews 会渲染背景颜色。您可以使用背景 属性.
从情节提要中设置 UIStackView 的背景
或在代码中:
if #available(iOS 14.0, *) {
stackView.backgroundColor = .green
} else {
// Fallback for older versions of iOS
}
有很好的答案,但我发现它们不完整,所以这是我基于其中最佳答案的版本:
/// This extension addes missing background color to stack views on iOS 13 and earlier
extension UIStackView {
private struct CustomAttributeNames {
static var _backgroundView = "_backgroundView"
}
@IBInspectable var customBackgroundColor: UIColor? {
get { backgroundColor }
set { setBackgroundColor(newValue) }
}
var backgroundView: UIView {
if let view = objc_getAssociatedObject(self, &CustomAttributeNames._backgroundView) as? UIView {
return view
}
let view = UIView(frame: bounds)
view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
insertSubview(view, at: 0)
objc_setAssociatedObject(self,
&CustomAttributeNames._backgroundView,
view,
objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
return view
}
func setBackgroundColor(_ color: UIColor?) {
backgroundColor = color
backgroundView.backgroundColor = color
}
}
我尝试在 Storyboard inspector 中将 UIStackView
背景从透明色更改为白色,但是在模拟时,堆栈视图的背景色仍然是透明色。
如何更改 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.
参考自HERE。
编辑:
您可以向 UIStackView
添加子视图,如前所述 HERE or in extension
的内容:
extension UIStackView {
func addBackground(color: UIColor) {
let subView = UIView(frame: bounds)
subView.backgroundColor = color
subView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
insertSubview(subView, at: 0)
}
}
您可以像这样使用它:
stackView.addBackground(color: .red)
我是这样做的:
@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
}
}
很有魅力
在iOS10中,@Arbitur的回答在设置颜色后需要一个setNeedsLayout。这是需要的更改:
override var backgroundColor: UIColor? {
get { return color }
set {
color = newValue
setNeedsLayout()
}
}
也许最简单、更易读且更简单的方法是将 UIStackView
嵌入到 UIView
中并为视图设置背景颜色。
并且不要忘记正确配置这两个视图之间的自动布局约束……;-)
TL;DR:官方方法是使用 addSubview:
方法将空视图添加到堆栈视图中,然后设置添加的视图背景。
说明:UIStackView是一个特殊的UIView子类,只做布局不做绘图。它的许多属性将无法正常工作。由于 UIStackView 只会布置其排列的子视图,这意味着您可以简单地使用 addSubview:
方法向其添加 UIView ,设置其约束和背景颜色。这是实现你想要的官方方式quoted from WWDC session
Pitiphong 是正确的,要获得具有背景颜色的堆栈视图,请执行以下操作...
let bg = UIView(frame: stackView.bounds)
bg.autoresizingMask = [.flexibleWidth, .flexibleHeight]
bg.backgroundColor = UIColor.red
stackView.insertSubview(bg, at: 0)
这将为您提供一个堆栈视图,其内容将放置在红色背景上。
要向堆栈视图添加填充以使内容不与边缘齐平,请在代码或情节提要中添加以下内容...
stackView.isLayoutMarginsRelativeArrangement = true
stackView.layoutMargins = UIEdgeInsets(top: 8, left: 8, bottom: 8, right: 8)
UIStackView *stackView;
UIView *stackBkg = [[UIView alloc] initWithFrame:CGRectZero];
stackBkg.backgroundColor = [UIColor redColor];
[self.view insertSubview:stackBkg belowSubview:stackView];
stackBkg.translatesAutoresizingMaskIntoConstraints = NO;
[[stackBkg.topAnchor constraintEqualToAnchor:stackView.topAnchor] setActive:YES];
[[stackBkg.bottomAnchor constraintEqualToAnchor:stackView.bottomAnchor] setActive:YES];
[[stackBkg.leftAnchor constraintEqualToAnchor:stackView.leftAnchor] setActive:YES];
[[stackBkg.rightAnchor constraintEqualToAnchor:stackView.rightAnchor] setActive:YES];
这适用于 Swift 3 和 iOS 10:
let stackView = UIStackView()
let subView = UIView()
subView.backgroundColor = .red
subView.translatesAutoresizingMaskIntoConstraints = false
stackView.addSubview(subView) // Important: addSubview() not addArrangedSubview()
// use whatever constraint method you like to
// constrain subView to the size of stackView.
subView.topAnchor.constraint(equalTo: stackView.topAnchor).isActive = true
subView.bottomAnchor.constraint(equalTo: stackView.bottomAnchor).isActive = true
subView.leftAnchor.constraint(equalTo: stackView.leftAnchor).isActive = true
subView.rightAnchor.constraint(equalTo: stackView.rightAnchor).isActive = true
// now add your arranged subViews...
stackView.addArrangedSubview(button1)
stackView.addArrangedSubview(button2)
你可以这样做:
stackView.backgroundColor = UIColor.blue
通过提供扩展来覆盖 backgroundColor
:
extension UIStackView {
override open var backgroundColor: UIColor? {
get {
return super.backgroundColor
}
set {
super.backgroundColor = newValue
let tag = -9999
for view in subviews where view.tag == tag {
view.removeFromSuperview()
}
let subView = UIView()
subView.tag = tag
subView.backgroundColor = newValue
subView.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(subView)
subView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
subView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
subView.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true
subView.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
}
}
}
这里是添加堆栈视图背景颜色的简要概述。
class RevealViewController: UIViewController {
@IBOutlet private weak var rootStackView: UIStackView!
创建带圆角的背景视图
private lazy var backgroundView: UIView = {
let view = UIView()
view.backgroundColor = .purple
view.layer.cornerRadius = 10.0
return view
}()
为了让它显示为背景,我们将它添加到索引 0 处的根堆栈视图的子视图数组中。这将它放在堆栈视图的排列视图后面。
private func pinBackground(_ view: UIView, to stackView: UIStackView) {
view.translatesAutoresizingMaskIntoConstraints = false
stackView.insertSubview(view, at: 0)
view.pin(to: stackView)
}
通过在 UIView 上使用一个小扩展,添加约束以将 backgroundView 固定到堆栈视图的边缘。
public extension UIView {
public func pin(to view: UIView) {
NSLayoutConstraint.activate([
leadingAnchor.constraint(equalTo: view.leadingAnchor),
trailingAnchor.constraint(equalTo: view.trailingAnchor),
topAnchor.constraint(equalTo: view.topAnchor),
bottomAnchor.constraint(equalTo: view.bottomAnchor)
])
}
}
从 viewDidLoad
pinBackground
override func viewDidLoad() {
super.viewDidLoad()
pinBackground(backgroundView, to: rootStackView)
}
参考自:HERE
UIStackView
是非渲染元素,因此不会在屏幕上绘制。这意味着更改 backgroundColor
基本上什么都不做。如果你想改变背景颜色,只需添加一个 UIView
作为子视图(未排列),如下所示:
extension UIStackView {
func addBackground(color: UIColor) {
let subview = UIView(frame: bounds)
subview.backgroundColor = color
subview.autoresizingMask = [.flexibleWidth, .flexibleHeight]
insertSubview(subview, at: 0)
}
}
Xamarin,C# 版本:
var stackView = new UIStackView { Axis = UILayoutConstraintAxis.Vertical };
UIView bg = new UIView(stackView.Bounds);
bg.AutoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight;
bg.BackgroundColor = UIColor.White;
stackView.AddSubview(bg);
子class UIStackView
class CustomStackView : UIStackView {
private var _bkgColor: UIColor?
override public var backgroundColor: UIColor? {
get { return _bkgColor }
set {
_bkgColor = newValue
setNeedsLayout()
}
}
private lazy var backgroundLayer: CAShapeLayer = {
let layer = CAShapeLayer()
self.layer.insertSublayer(layer, at: 0)
return layer
}()
override public func layoutSubviews() {
super.layoutSubviews()
backgroundLayer.path = UIBezierPath(rect: self.bounds).cgPath
backgroundLayer.fillColor = self.backgroundColor?.cgColor
}
}
然后在你的class
yourStackView.backgroundColor = UIColor.lightGray
你可以在 StackView 中插入一个子层,它对我有用:
@interface StackView ()
@property (nonatomic, strong, nonnull) CALayer *ly;
@end
@implementation StackView
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
_ly = [CALayer new];
[self.layer addSublayer:_ly];
}
return self;
}
- (void)setBackgroundColor:(UIColor *)backgroundColor {
[super setBackgroundColor:backgroundColor];
self.ly.backgroundColor = backgroundColor.CGColor;
}
- (void)layoutSubviews {
self.ly.frame = self.bounds;
[super layoutSubviews];
}
@end
您可以对 UIStackView
extension UIStackView {
func setBackgroundColor(_ color: UIColor) {
let backgroundView = UIView(frame: .zero)
backgroundView.backgroundColor = color
backgroundView.translatesAutoresizingMaskIntoConstraints = false
self.insertSubview(backgroundView, at: 0)
NSLayoutConstraint.activate([
backgroundView.topAnchor.constraint(equalTo: self.topAnchor),
backgroundView.leadingAnchor.constraint(equalTo: self.leadingAnchor),
backgroundView.bottomAnchor.constraint(equalTo: self.bottomAnchor),
backgroundView.trailingAnchor.constraint(equalTo: self.trailingAnchor)
])
}
}
用法:
yourStackView.setBackgroundColor(.black)
我对 UI 组件的子类化有点怀疑。这就是我的使用方式,
struct CustomAttributeNames{
static var _backgroundView = "_backgroundView"
}
extension UIStackView{
var backgroundView:UIView {
get {
if let view = objc_getAssociatedObject(self, &CustomAttributeNames._backgroundView) as? UIView {
return view
}
//Create and add
let view = UIView(frame: .zero)
view.translatesAutoresizingMaskIntoConstraints = false
insertSubview(view, at: 0)
NSLayoutConstraint.activate([
view.topAnchor.constraint(equalTo: self.topAnchor),
view.leadingAnchor.constraint(equalTo: self.leadingAnchor),
view.bottomAnchor.constraint(equalTo: self.bottomAnchor),
view.trailingAnchor.constraint(equalTo: self.trailingAnchor)
])
objc_setAssociatedObject(self,
&CustomAttributeNames._backgroundView,
view,
objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
return view
}
}
}
这是用法,
stackView.backgroundView.backgroundColor = .white
stackView.backgroundView.layer.borderWidth = 2.0
stackView.backgroundView.layer.borderColor = UIColor.red.cgColor
stackView.backgroundView.layer.cornerRadius = 4.0
注意:使用这种方法,如果要设置边框,则必须在 stackView 上设置 layoutMargins
以便边框可见。
您无法将背景添加到堆栈视图。 但是您可以做的是在视图中添加堆栈视图,然后设置视图背景,这将完成工作。 *它不会中断堆栈视图的流程。 希望这会有所帮助。
我们可以像这样自定义 class StackView
:
class StackView: UIStackView {
lazy var backgroundView: UIView = {
let otherView = UIView()
addPinedSubview(otherView)
return otherView
}()
}
extension UIView {
func addPinedSubview(_ otherView: UIView) {
addSubview(otherView)
otherView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
otherView.trailingAnchor.constraint(equalTo: trailingAnchor),
otherView.topAnchor.constraint(equalTo: topAnchor),
otherView.heightAnchor.constraint(equalTo: heightAnchor),
otherView.widthAnchor.constraint(equalTo: widthAnchor),
])
}
}
并且可以这样使用:
let stackView = StackView()
stackView.backgroundView.backgroundColor = UIColor.lightGray
这比其他人建议的添加扩展函数 func addBackground(color: UIColor)
稍微好一些。背景视图是惰性的,因此在您实际调用 stackView.backgroundView.backgroundColor = ...
之前不会创建它。并且 setting/changing 背景颜色多次不会导致在堆栈视图中插入多个子视图。
如果您想从设计器本身进行控制,请将此扩展添加到堆栈视图
@IBInspectable var customBackgroundColor: UIColor?{
get{
return backgroundColor
}
set{
backgroundColor = newValue
let subview = UIView(frame: bounds)
subview.backgroundColor = newValue
subview.autoresizingMask = [.flexibleWidth, .flexibleHeight]
insertSubview(subview, at: 0)
}
}
值得指出的是,从 iOS 14 开始,UIStackViews 会渲染背景颜色。您可以使用背景 属性.
从情节提要中设置 UIStackView 的背景或在代码中:
if #available(iOS 14.0, *) {
stackView.backgroundColor = .green
} else {
// Fallback for older versions of iOS
}
有很好的答案,但我发现它们不完整,所以这是我基于其中最佳答案的版本:
/// This extension addes missing background color to stack views on iOS 13 and earlier
extension UIStackView {
private struct CustomAttributeNames {
static var _backgroundView = "_backgroundView"
}
@IBInspectable var customBackgroundColor: UIColor? {
get { backgroundColor }
set { setBackgroundColor(newValue) }
}
var backgroundView: UIView {
if let view = objc_getAssociatedObject(self, &CustomAttributeNames._backgroundView) as? UIView {
return view
}
let view = UIView(frame: bounds)
view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
insertSubview(view, at: 0)
objc_setAssociatedObject(self,
&CustomAttributeNames._backgroundView,
view,
objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
return view
}
func setBackgroundColor(_ color: UIColor?) {
backgroundColor = color
backgroundView.backgroundColor = color
}
}