Я спробував змінити UIStackView
фон з ясного на білий у інспектора Storyboard, але при моделюванні колір тла подання стека все ще має чіткий колір.
Як я можу змінити колір тла UIStackView
?
Я спробував змінити UIStackView
фон з ясного на білий у інспектора Storyboard, але при моделюванні колір тла подання стека все ще має чіткий колір.
Як я можу змінити колір тла UIStackView
?
Відповіді:
Ви не можете цього зробити -
UIStackView
це вид, щоdrawRect()
не малює, тобто його не називають, а колір тла ігнорується. Якщо ви відчайдушно хочете кольору фону, подумайте про те, щоб розмістити стек всередині іншогоUIView
і надати цьому виду колір фону.
Посилання з ТУТ .
Редагувати:
Ви можете додати subView, 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)
drawRect()
називається. Ви можете просто перевірити підкласифікаціюUIStackView
if let backgroundView = self.subviews.first(where: {$0.tag == 123}) {
. Якщо так, я змінюю колір тла цього виду.
Я роблю це так:
@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
}
}
Працює як шарм
@IBDesignable class StackView
Що дозволить вам проектувати на дошці Story. Мене дуже не хвилює додавання фону під час виконання, але дуже складно спроектувати стек-огляд, коли у нього немає кольору на дошці
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)
}
}
Можливо, найпростішим, більш читабельним і менш хакітним способом було б вбудовувати UIStackView
в а UIView
та встановити колір фону для подання.
І не забудьте правильно настроїти обмеження для автоматичного макета між цими двома видами перегляду… ;-)
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)
TL; DR: Офіційний спосіб зробити це - додавши порожній вигляд у подання стека за допомогою addSubview:
методу та встановивши натомість фон доданого перегляду.
Пояснення: UIStackView - це спеціальний підклас UIView, який робить лише макет не креслення. Так багато його властивостей не працюватимуть як завжди. А оскільки UIStackView буде розміщувати лише свої підпорядковані підгляди, це означає, що ви можете просто додати йому UIView addSubview:
методом, встановити його обмеження та колір фону. Це офіційний спосіб досягти того, що ви хочете цитувати з сесії WWDC
Для мене це працює у 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)
У iOS10 відповідь @ Arbitur потребує setNeedsLayout після встановлення кольору. Це необхідна зміна:
override var backgroundColor: UIColor? {
get { return color }
set {
color = newValue
setNeedsLayout()
}
}
backgroundColor
перш ніж додати його до superview
він працює на ios10 і ios9, однак, якщо ви оновили backgroundColor
після його layoutSubviews()
функція була викликана вона просто Wouldnt оновлюють backgroundColor
з backgroundLayer
не означає ніякого візуального оновлення. Виправлено зараз, дякую, що вказали на це.
Ось короткий огляд для додавання кольору фону фонового зображення.
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)
}
Додайте обмеження, щоб закріпити 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
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)
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);
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];
Підклас 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
Ви можете вставити підшар в 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
Я трохи скептично ставлюся до компонентів інтерфейсу субкласифікації. Ось як я його використовую,
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, щоб межа була видимою.
Ви не можете додати тло для перегляду стека. Але те, що ви можете зробити, це додати стек-огляд у подання, а потім встановити фон перегляду, це дозволить виконати роботу. * Він не перерве потоки стек-огляду. Сподіваюсь, це допоможе.
Ми можемо мати спеціальний клас на 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 = ...
. А встановлення / зміна кольору фону кілька разів не призведе до того, що в подання стека буде вставлено декілька підвидів.
Якщо ви хочете керувати з боку самого дизайнера, додайте це розширення до подання стека
@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)
}
}
Ви можете зробити це так:
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
}
}
}