как изменить цвет фона UIStackView?



Я пытался изменить UIStackView фон от прозрачного до белого в Инспекторе раскадровки, но при моделировании цвет фона представления стека по-прежнему имеет четкий цвет.

Как я могу изменить цвет фона UIStackView?

652   12  

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 С viewDidLoad

override 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

    Ничего не найдено.