मैंने UIStackView
स्टोरीबोर्ड इंस्पेक्टर में स्पष्ट से पृष्ठभूमि को सफेद में बदलने की कोशिश की , लेकिन जब अनुकरण करते हैं, तो स्टैक दृश्य की पृष्ठभूमि का रंग अभी भी एक स्पष्ट रंग है।
मैं पृष्ठभूमि का रंग कैसे बदल सकता हूं UIStackView
?
मैंने UIStackView
स्टोरीबोर्ड इंस्पेक्टर में स्पष्ट से पृष्ठभूमि को सफेद में बदलने की कोशिश की , लेकिन जब अनुकरण करते हैं, तो स्टैक दृश्य की पृष्ठभूमि का रंग अभी भी एक स्पष्ट रंग है।
मैं पृष्ठभूमि का रंग कैसे बदल सकता हूं UIStackView
?
जवाबों:
आप ऐसा नहीं कर सकते -
UIStackView
एक गैर-ड्राइंग दृश्य है, जिसका अर्थ है किdrawRect()
इसे कभी नहीं बुलाया जाएगा और इसकी पृष्ठभूमि का रंग अनदेखा किया गया है। यदि आप एक पृष्ठभूमि रंग चाहते हैं, तो स्टैक दृश्य को दूसरे के अंदर रखनेUIView
और उस दृश्य को एक पृष्ठभूमि रंग देने पर विचार करें।
यहाँ से संदर्भ ।
संपादित करें:
आप यहां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()
कहा जाता है। आप बस subclassingUIStackView
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
जो आपको स्टोरी बोर्ड पर डिज़ाइन करने की अनुमति देगा। मुझे नहीं रन टाइम पर एक पृष्ठभूमि जोड़ने के लिए ज्यादा परवाह है, लेकिन यह stackview जब यह कहानी बोर्ड पर कोई रंग है डिजाइन करने के लिए बहुत कठिन है
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)
}
}
हो सकता है कि सबसे आसान, अधिक पठनीय और कम hacky रास्ता एम्बेड करने के लिए किया जाएगा 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 एक विशेष यूविवि उपवर्ग है जो केवल लेआउट को ड्राइंग नहीं करता है। इसके कई गुण हमेशा की तरह काम नहीं करेंगे। और चूंकि UIStackView अपने व्यवस्थित उप-लेआउटों को ही लेआउट करेगा, इसका मतलब है कि आप बस इसे addSubview:
विधि के साथ एक UIView जोड़ सकते हैं , इसकी बाधाओं और पृष्ठभूमि का रंग सेट कर सकते हैं । यह आधिकारिक तरीका है जिसे आप डब्ल्यूडब्ल्यूडीसी सत्र से उद्धृत करना चाहते हैं
यह स्विफ्ट 3 और आईओएस 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()
फ़ंक्शन को कॉल करने के बाद इसे अपडेट किया 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)
}
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)
ज़मारिन, सी # संस्करण:
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
इस तरह एक कस्टम वर्ग हो सकता है :
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
}
}
}
BoxView का प्रयास करें । यह UIStackView के समान है, लेकिन यह अधिक लेआउटिंग विकल्पों का प्रतिपादन और समर्थन करता है।