vertical objective how example ios swift uistackview

ios - objective - uistackview swift 3



¿Cómo cambiar el color de fondo de UIStackView? (16)

Traté de cambiar el fondo UIStackView de claro a blanco en el inspector de Storyboard, pero al simular, el color de fondo de la vista de pila todavía tiene un color claro.
¿Cómo puedo cambiar el color de fondo de un UIStackView ?


No puede hacer esto: UIStackView es una vista sin dibujo, lo que significa que nunca se llama a drawRect() y se ignora su color de fondo. Si desea desesperadamente un color de fondo, considere colocar la vista de pila dentro de otra UIView y darle a esa vista un color de fondo.

Referencia desde HERE .

EDITAR:

Puede agregar una subvista a UIStackView como se menciona HERE o en esta respuesta (a continuación) y asignarle un color. Echa un vistazo a la extension continuación para eso:

extension UIStackView { func addBackground(color: UIColor) { let subView = UIView(frame: bounds) subView.backgroundColor = color subView.autoresizingMask = [.flexibleWidth, .flexibleHeight] insertSubview(subView, at: 0) } }

Y puedes usarlo como:

stackView.addBackground(color: .red)


Aquí hay una breve descripción general para agregar una vista de pila Color de fondo.

class RevealViewController: UIViewController { @IBOutlet private weak var rootStackView: UIStackView!

Crear vista de fondo con esquinas redondeadas

private lazy var backgroundView: UIView = { let view = UIView() view.backgroundColor = .purple view.layer.cornerRadius = 10.0 return view }()

Para que aparezca como fondo, lo agregamos a la matriz de subvistas de la vista de pila raíz en el índice 0. Eso lo coloca detrás de las vistas organizadas de la vista de pila.

private func pinBackground(_ view: UIView, to stackView: UIStackView) { view.translatesAutoresizingMaskIntoConstraints = false stackView.insertSubview(view, at: 0) view.pin(to: stackView) }

Agregue restricciones para anclar el backgroundView a los bordes de la vista de la pila, utilizando una pequeña extensión en 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) ]) } }

llame al pinBackground desde viewDidLoad

override func viewDidLoad() { super.viewDidLoad() pinBackground(backgroundView, to: rootStackView) }

Referencia de: useyourloaf.com/blog/stack-view-background-color


En iOS10, la respuesta de @ Arbitur necesita un setNeedsLayout después de configurar el color. Este es el cambio que se necesita:

override var backgroundColor: UIColor? { get { return color } set { color = newValue setNeedsLayout() } }


Esto funciona para mí en Swift 3 y 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)


Lo hago así:

@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 } }

Funciona de maravilla


Pitiphong es correcto, para obtener una vista de pila con un color de fondo, haga algo como lo siguiente ...

let bg = UIView(frame: stackView.bounds) bg.autoresizingMask = [.flexibleWidth, .flexibleHeight] bg.backgroundColor = UIColor.red stackView.insertSubview(bg, at: 0)

Esto le dará una vista de pila cuyo contenido se colocará sobre un fondo rojo.

Para agregar relleno a la vista de pila para que los contenidos no estén alineados con los bordes, agregue lo siguiente en el código o en el guión gráfico ...

stackView.isLayoutMarginsRelativeArrangement = true stackView.layoutMargins = UIEdgeInsets(top: 8, left: 8, bottom: 8, right: 8)


Podría hacer una pequeña extensión de 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) ]) } }

Uso:

yourStackView.setBackgroundColor(.black)


Podrías hacerlo así:

stackView.backgroundColor = UIColor.blue

Al proporcionar una extensión para anular el 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 } } }


Puede insertar una subcapa en StackView, me funciona:

@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


Quizás la forma más fácil, más legible y menos hacky sería incrustar el UIStackView en un UIView y establecer el color de fondo a la vista.

Y no olvide configurar correctamente las restricciones de diseño automático entre esas dos vistas ... ;-)


Soy un poco escéptico en Subclasificar componentes de la interfaz de usuario. Así es como lo estoy usando,

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 } } }

Y este es el uso,

stackView.backgroundView.backgroundColor = .white stackView.backgroundView.layer.borderWidth = 2.0 stackView.backgroundView.layer.borderColor = UIColor.red.cgColor stackView.backgroundView.layer.cornerRadius = 4.0

Nota: con este enfoque, si desea establecer el borde, debe establecer layoutMargins en el stackView para que el borde sea visible.


Subclase 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 } }

Luego en tu clase

yourStackView.backgroundColor = UIColor.lightGray


TL; DR: la forma oficial de hacerlo es agregando una vista vacía a la vista de pila usando el método addSubview: y estableciendo el fondo de la vista agregada.

La explicación: UIStackView es una subclase especial de UIView que solo hace que el diseño no se dibuje. Muchas de sus propiedades no funcionarán como de costumbre. Y dado que UIStackView diseñará solo sus subvistas organizadas, esto significa que simplemente puede agregarle una UIView con addSubview: método, establecer sus restricciones y color de fondo. Esta es la forma oficial de lograr lo que quiere citado de la sesión de WWDC


Xamarin, versión 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);


UIStackView es un elemento que no se representa y, como tal, no se dibuja en la pantalla. Esto significa que cambiar backgroundColor esencialmente no hace nada. Si desea cambiar el color de fondo, simplemente agregue una vista UIView como una subvista (que no está organizada) como a continuación:

extension UIStackView { func addBackground(color: UIColor) { let subview = UIView(frame: bounds) subview.backgroundColor = color subview.autoresizingMask = [.flexibleWidth, .flexibleHeight] insertSubview(subview, at: 0) } }


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];