Я попытался изменить фон UIStackView
с четкого на белый в инспекторе раскадровки, но при имитации цвет фона в представлении стека по-прежнему имеет четкий цвет.
Как изменить цвет фона UIStackView
?
Как изменить цвет фона UIStackView?
Ответ 1
Вы не можете сделать это -
UIStackView
это вид без рисунка, что означает, чтоdrawRect()
никогда не вызывается, а его цвет фона игнорируется. если ты отчаянно хотите цвет фона, рассмотрите возможность размещения стека внутри другогоUIView
и предоставив этому виду цвет фона.
Ссылка от ЗДЕСЬ.
EDIT:
Вы можете добавить подпункт к UIStackView
, как упомянуто ЗДЕСЬ или в этом ответе (ниже), и назначить ему цвет. Проверьте ниже 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)
Ответ 2
Я делаю это так:
@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
}
}
Работает как шарм
Ответ 3
UIStackView
- это элемент без рендеринга, и, как таковой, он не отображается на экране. Это означает, что изменение backgroundColor
сути ничего не делает. Если вы хотите изменить цвет фона, просто добавьте к нему UIView
как подпредставление (которое не организовано), как UIView
ниже:
extension UIStackView {
func addBackground(color: UIColor) {
let subview = UIView(frame: bounds)
subview.backgroundColor = color
subview.autoresizingMask = [.flexibleWidth, .flexibleHeight]
insertSubview(subview, at: 0)
}
}
Ответ 4
Возможно, самый простой, более читаемый и менее хакерский способ - вставить UIStackView
в UIView
и установить цвет фона для представления.
И не забудьте правильно настроить ограничения автоматического макета между этими двумя видами...;-)
Ответ 5
TL; DR: официальный способ сделать это - добавить пустой вид в стек, используя метод addSubview:
, и вместо этого установить вместо этого дополнительный фон.
Объяснение: UIStackView - это специальный подкласс UIView, который выполняет только макет, а не чертеж. Так что многие из его свойств не будут работать как обычно. И поскольку UIStackView будет компоновать только расположенные подразделы, это означает, что вы можете просто добавить его UIView с помощью метода addSubview:
, установить его ограничения и цвет фона. Это официальный способ достижения желаемого цитируемого на сессии WWDC
Ответ 6
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)
Ответ 7
В iOS10 для ответа @Arbitur требуется setNeedsLayout после установки цвета. Это изменение необходимо:
override var backgroundColor: UIColor? {
get { return color }
set {
color = newValue
setNeedsLayout()
}
}
Ответ 8
Это работает для меня в 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)
Ответ 9
Ниже приведен краткий обзор добавления цвета фона в стеке.
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)
}
Ссылка из: ЗДЕСЬ
Ответ 10
Вы можете сделать небольшое расширение 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)
Ответ 11
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];
Ответ 12
Xamarin, С# версия:
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);
Ответ 13
Подкласс 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
}
}
Тогда в вашем классе
yourStackView.backgroundColor = UIColor.lightGray
Ответ 14
Вы можете вставить подслой в 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
Ответ 15
Я немного скептически отношусь к компонентам UC. Вот как я это использую,
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
Примечание. При таком подходе, если вы хотите установить границу, вы должны установить layoutMargins
в stackView, чтобы граница была видимой.
Ответ 16
Вы не можете добавить фон в стек просмотра. Но то, что вы можете сделать, это добавить представление стека в представление, а затем установить фон представления, и это сделает работу. * Он не будет прерывать потоки стека. Надеюсь, это поможет.
Ответ 17
Вы можете сделать это следующим образом:
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
}
}
}