UIStackView
Storyboard denetçisinde arka planı açıktan beyaza değiştirmeye çalıştım , ancak simüle ederken, yığın görünümünün arka plan renginin hala açık bir rengi var.
A'nın arka plan rengini nasıl değiştirebilirim UIStackView
?
UIStackView
Storyboard denetçisinde arka planı açıktan beyaza değiştirmeye çalıştım , ancak simüle ederken, yığın görünümünün arka plan renginin hala açık bir rengi var.
A'nın arka plan rengini nasıl değiştirebilirim UIStackView
?
Yanıtlar:
Bunu yapamazsınız -
UIStackView
çizim yapılmayan bir görünümdür, yanidrawRect()
asla çağrılmaz ve arka plan rengi yok sayılır. Umutsuzca bir arka plan rengi istiyorsanız, yığın görünümünü bir diğerinin içine yerleştirmeyiUIView
ve bu görünüme bir arka plan rengi vermeyi düşünün .
BURADAN referans .
DÜZENLE:
BURAYA veya bu cevapta (aşağıda)UIStackView
belirtildiği gibi bir subView ekleyebilir ve buna bir renk atayabilirsiniz. Bunun için aşağıya bakın:extension
extension UIStackView {
func addBackground(color: UIColor) {
let subView = UIView(frame: bounds)
subView.backgroundColor = color
subView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
insertSubview(subView, at: 0)
}
}
Ve bunu şöyle kullanabilirsiniz:
stackView.addBackground(color: .red)
drawRect()
denir. Sadece alt sınıflama ile test edebilirsinizUIStackView
if let backgroundView = self.subviews.first(where: {$0.tag == 123}) {
. Öyleyse, o görünümün arka plan rengini değiştiririm.
Bunu şöyle yaparım:
@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
}
}
Tıkır tıkır çalışıyor
@IBDesignable class StackView
Hikaye panosunda tasarlamanıza izin verir. Çalışma zamanında bir arka plan eklemek için pek umurumda değil, ancak hikaye tahtasında renk olmadığında yığın görünümünü tasarlamak çok zor
UIStackView
oluşturmayan bir öğedir ve bu nedenle ekranda çizilmez. Bu, değişmenin backgroundColor
aslında hiçbir şey yapmadığı anlamına gelir . Arka plan rengini değiştirmek istiyorsanız, UIView
a'yı aşağıdaki gibi bir alt görünüm (düzenlenmemiş olan) olarak ekleyin :
extension UIStackView {
func addBackground(color: UIColor) {
let subview = UIView(frame: bounds)
subview.backgroundColor = color
subview.autoresizingMask = [.flexibleWidth, .flexibleHeight]
insertSubview(subview, at: 0)
}
}
Belki de en kolay, daha okunaklı ve daha az hacky yolu, UIStackView
içine gömmek UIView
ve arka plan rengini görünüme ayarlamak olacaktır.
Ve bu iki görünüm arasındaki Otomatik Mizanpaj kısıtlamalarını düzgün bir şekilde yapılandırmayı unutmayın ... ;-)
Pitiphong doğrudur, arka plan rengiyle bir yığın görünümü elde etmek için aşağıdakine benzer bir şey yapın ...
let bg = UIView(frame: stackView.bounds)
bg.autoresizingMask = [.flexibleWidth, .flexibleHeight]
bg.backgroundColor = UIColor.red
stackView.insertSubview(bg, at: 0)
Bu, içeriği kırmızı bir arka plan üzerine yerleştirilecek bir yığın görünümü verecektir.
İçeriğin kenarlarla aynı hizada olmaması için yığın görünümüne dolgu eklemek için aşağıdakileri kod veya film şeridine ekleyin ...
stackView.isLayoutMarginsRelativeArrangement = true
stackView.layoutMargins = UIEdgeInsets(top: 8, left: 8, bottom: 8, right: 8)
TL; DR: Bunu yapmanın resmi yolu, addSubview:
yöntemi kullanarak yığın görünümüne boş bir görünüm eklemek ve bunun yerine eklenen görünüm arka planını ayarlamaktır.
Açıklama: UIStackView, yalnızca düzeni çizmeyen özel bir UIView alt sınıfıdır. Pek çok özelliği her zamanki gibi çalışmaz. Ve UIStackView yalnızca düzenlenmiş alt görünümlerini düzenleyeceği için, bunu addSubview:
yöntemle bir UIView ekleyebileceğiniz , kısıtlamalarını ve arka plan rengini ayarlayabileceğiniz anlamına gelir . WWDC oturumundan alıntılanmasını istediğiniz resmi elde etmenin resmi yolu budur
Swift 3 ve iOS 10'da bu benim için çalışıyor:
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)
İOS10'da, renk ayarlandıktan sonra @ Arbitur'un cevabının setNeedsLayout'a ihtiyacı var. Gereken değişiklik bu:
override var backgroundColor: UIColor? {
get { return color }
set {
color = newValue
setNeedsLayout()
}
}
backgroundColor
Bir eklemeden önce superview
o ios10 ve ios9 çalışır güncellenen eğer, ancak, backgroundColor
onun ardından layoutSubviews()
fonksiyon sadece wouldnt güncelleme denirdi backgroundColor
ait backgroundLayer
hiçbir görsel güncellemesini anlamı. Şimdi düzeltildi, işaret ettiğiniz için teşekkürler.
Yığın görünümü Arka Plan Rengi eklemek için kısa bir genel bakış.
class RevealViewController: UIViewController {
@IBOutlet private weak var rootStackView: UIStackView!
Köşeleri yuvarlatılmış arka plan görünümü oluşturma
private lazy var backgroundView: UIView = {
let view = UIView()
view.backgroundColor = .purple
view.layer.cornerRadius = 10.0
return view
}()
Arka plan olarak görünmesini sağlamak için, dizini 0 dizinindeki kök yığını görünümünün alt görünümler dizisine ekleriz.
private func pinBackground(_ view: UIView, to stackView: UIStackView) {
view.translatesAutoresizingMaskIntoConstraints = false
stackView.insertSubview(view, at: 0)
view.pin(to: stackView)
}
UIView'de küçük bir uzantı kullanarak backgroundView öğesini yığın görünümünün kenarlarına sabitlemek için kısıtlamalar ekleyin.
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)
])
}
}
call pinBackground
danviewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
pinBackground(backgroundView, to: rootStackView)
}
Referans kaynağı: HERE
Xamarin, C # sürümü:
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);
Küçük bir uzantısı yapabilirsiniz 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)
])
}
}
Kullanımı:
yourStackView.setBackgroundColor(.black)
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];
Alt sınıf 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
}
}
Sonra sınıfında
yourStackView.backgroundColor = UIColor.lightGray
StackView'e bir alt katman ekleyebilirsiniz, bana çalışır:
@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
Alt Sınıflandırma UI bileşenlerinde biraz şüpheliyim. Ben böyle kullanıyorum,
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
}
}
}
Ve bu kullanım,
stackView.backgroundView.backgroundColor = .white
stackView.backgroundView.layer.borderWidth = 2.0
stackView.backgroundView.layer.borderColor = UIColor.red.cgColor
stackView.backgroundView.layer.cornerRadius = 4.0
Not: Bu yaklaşımla, kenarlığı ayarlamak istiyorsanız layoutMargins
, stackView üzerinde kenarlığın görünür olması için ayarlamanız gerekir .
Stackview'a arka plan ekleyemezsiniz. Ancak, bir görünüme yığın görünümü eklemek ve daha sonra görünümün arka planını ayarlamak işinizi halledecektir. * Stackview akışlarını kesmeyecek. Umarım bu yardımcı olur.
Bunun StackView
gibi özel bir sınıfımız olabilir :
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),
])
}
}
Ve şu şekilde kullanılabilir:
let stackView = StackView()
stackView.backgroundView.backgroundColor = UIColor.lightGray
Bu, func addBackground(color: UIColor)
başkalarının önerdiği gibi bir uzantı işlevi eklemekten biraz daha iyidir . Arka plan görünümü tembeldir, böylece siz gerçekten arama yapana kadar oluşturulmaz stackView.backgroundView.backgroundColor = ...
. Arka plan rengini birden çok kez ayarlamak / değiştirmek, yığın görünümüne birden çok alt görünümün eklenmesine neden olmaz.
Tasarımcının kendisinden kontrol etmek istiyorsanız, bu uzantıyı yığın görünümüne ekleyin
@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)
}
}
Bunu şu şekilde yapabilirsiniz:
stackView.backgroundColor = UIColor.blue
Aşağıdakileri geçersiz kılmak için bir uzantı sağlayarak 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
}
}
}