12 ответов:
ты не можешь этого сделать -
UIStackViewЭто не чертежный вид, что означает, чтоdrawRect()никогда не вызывается и его цвет фона игнорируется. Если вы отчаянно хотите цвет фона, рассмотрите возможность размещения стека внутри другойUIViewи придание этому виду цвета фона.справка здесь.
Я делаю это так:
@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 } }работает
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) } }
TL; DR: официальный способ сделать это-добавить пустое представление в представление стека с помощью
addSubview:метод и установить добавленный вид фона вместо этого.объяснение: UIStackView-это специальный подкласс UIView, который только не рисует макет. Так что многие из его свойств не будут работать как обычно. И поскольку UIStackView будет размещать только свои упорядоченные подвиды, это означает, что вы можете просто добавить его в UIView с
addSubview:метод, установите его ограничения и цвет фона. Это официальный способ достичь того, что вы хотите цитата из сессии WWDC
возможно, самым простым, более читаемым и менее хакерским способом было бы встроить
UIStackViewнаUIViewи установите цвет фона для представления.и не забудьте правильно настроить ограничения автоматической компоновки между этими двумя представлениями...; -)
Pitiphong правильно, чтобы получить stackview с цветом фона сделать что-то вроде следующего...
let bg = UIView(frame: stackView.bounds) bg.autoresizingMask = [.flexibleWidth, .flexibleHeight] bg.backgroundColor = UIColor.red stackView.addSubview(bg)это даст вам stackview, содержимое которого будет размещено на красном фоне.
чтобы добавить заполнение в stackview, чтобы содержимое не было заподлицо с краями, добавьте следующее в коде или на раскадровке...
stackView.isLayoutMarginsRelativeArrangement = true stackView.layoutMargins = UIEdgeInsets(top: 8, left: 8, bottom: 8, right: 8)
в iOS10, ответы @Arbitur нужен setNeedsLayout после того, как цвет расположен. Это изменение, которое необходимо:
override var backgroundColor: UIColor? { get { return color } set { color = newValue setNeedsLayout() } }
это работает для меня в 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)
вот краткий обзор для добавления цвета фона вида стека.
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 }()чтобы он отображался в качестве фона, мы добавляем его в массив subviews корневого стекового представления с индексом 0. Это помещает его за упорядоченные представления вида стека.
private func pinBackground(_ view: UIView, to stackView: UIStackView) { view.translatesAutoresizingMaskIntoConstraints = false stackView.insertSubview(view, at: 0) view.pin(to: stackView) }добавьте ограничения, чтобы закрепить backgroundView к краям представления стека, используя небольшое расширение Наследник UIView.
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) ]) } }вызов
pinBackgroundСviewDidLoadoverride func viewDidLoad() { super.viewDidLoad() pinBackground(backgroundView, to: rootStackView) }справка: здесь
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];
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);
вы могли бы сделать это вот так:
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 } } }
Comments