NSView के लिए पृष्ठभूमि का रंग बदलने का सबसे अच्छा तरीका है


149

मैं सबसे अच्छा तरीका बदलने के लिए की तलाश में हूँ backgroundColorएक की NSView। मैं भी के लिए उपयुक्त alphaमुखौटा सेट करने में सक्षम होना चाहते हैं NSView। कुछ इस तरह:

myView.backgroundColor = [NSColor colorWithCalibratedRed:0.227f 
                                                   green:0.251f 
                                                    blue:0.337 
                                                   alpha:0.8];

मुझे लगता NSWindowहै कि यह विधि है, और मैं का एक बड़ा प्रशंसक NSColorWheel, या NSImageपृष्ठभूमि विकल्प नहीं हूँ , लेकिन अगर वे सबसे अच्छा कर रहे हैं, का उपयोग करने के लिए तैयार।

जवाबों:


134

हाँ, आपका अपना जवाब सही था। आप कोको विधियों का भी उपयोग कर सकते हैं:

- (void)drawRect:(NSRect)dirtyRect {
    // set any NSColor for filling, say white:
    [[NSColor whiteColor] setFill];
    NSRectFill(dirtyRect);
    [super drawRect:dirtyRect];
}

स्विफ्ट में:

class MyView: NSView {

    override func draw(_ dirtyRect: NSRect) {
        super.draw(dirtyRect)

        // #1d161d
        NSColor(red: 0x1d/255, green: 0x16/255, blue: 0x1d/255, alpha: 1).setFill()
        dirtyRect.fill()
    }

}

18
NSRectFillNSCompositeCopyभरण करने के लिए उपयोग करता है, इसलिए यह इसके पीछे कुछ भी लिख देगा - यह किसी भी पूर्वज विचारों के शीर्ष पर समग्र नहीं होगा। आंशिक रूप से (या पूरी तरह से) पारदर्शी रंग के साथ भरने के लिए, ऑपरेशन के साथ NSRectFillUsingOperation डेवलपरNSCompositeSourceOver . apple.com/mac/library/documentation/Cocoa/Reference/… का उपयोग करें ।
पीटर होसी

ओह, यह समझ में आता है। मैंने NSRectFill की कोशिश की, लेकिन पारदर्शिता काम नहीं आई। मैं कोकोआ टच से कोको में आ रहा हूं, और यह देखकर आश्चर्यचकित हूं कि कुछ मायनों में कोको टच फ्रेमवर्क अधिक पूर्ण है!)। मैं NSView के लिए एक क्लास एक्सटेंशन बनाने के बारे में सोच रहा था जो आपको पृष्ठभूमि को स्थापित करने की अनुमति देगा जैसे आप एक NSWindow या UIView कर सकते हैं, लेकिन मुझे नहीं लगता कि आप एक एक्सटेंशन के साथ ड्रॉअर को ओवरराइड कर सकते हैं।
बैडपिरेट

क्षमा करें, मैंने पारदर्शिता वाला भाग याद किया। हाँ, कोको टच कई चीजों को आसान बनाता है। यदि आप भी कोको स्पर्श कर रहे हैं तो आपका स्वयं का उत्तर वास्तव में बेहतर है, क्योंकि यह अधिक पोर्टेबल है।
मोहनसेन

मुझे यह नहीं मिला, यह दृश्य के शीर्ष पर सफेद रंग खींच रहा है, मैंने अभी कोशिश की है। पृष्ठभूमि रंग के बारे में सवाल नहीं था?
aneuryzm

@Patrick - आपको सुपर ड्रॉरेक्ट कॉल करने की आवश्यकता हो सकती है :) या यदि आपके पास कुछ अन्य चीजें हैं जो पृष्ठभूमि के शीर्ष पर खींची जानी हैं, तो सुनिश्चित करें कि वे NSRectFill कॉल के बाद हैं।
बैडपिरेट

116

एक आसान, कुशल समाधान है कि कोर बैकिंग स्टोर के रूप में कोर एनिमेशन लेयर का उपयोग करने के लिए व्यू को कॉन्फ़िगर करें। फिर आप -[CALayer setBackgroundColor:]परत की पृष्ठभूमि का रंग सेट करने के लिए उपयोग कर सकते हैं ।

- (void)awakeFromNib {
   self.wantsLayer = YES;  // NSView will create a CALayer automatically
}

- (BOOL)wantsUpdateLayer {
   return YES;  // Tells NSView to call `updateLayer` instead of `drawRect:`
}

- (void)updateLayer {
   self.layer.backgroundColor = [NSColor colorWithCalibratedRed:0.227f 
                                                          green:0.251f 
                                                           blue:0.337 
                                                          alpha:0.8].CGColor;
}

बस!


6
सावधान: बहुत ही रचनात्मक तरीकों से आपके आवेदन में आपके पास मौजूद किसी भी WebViews को कॉल करना setLayer:या setWantsLayer:तोड़ना! (यहां तक ​​कि अलग-अलग खिड़कियों में ...)
rluba

1
मेथोड setWantsLayer:में परिभाषित किया गया है: परत-समर्थित दृश्यों का उपयोग करते समय आपको कभी भी परत के साथ सीधे संपर्क नहीं करना चाहिए । कब setWantsLayer:और setLayer:कहा जाता है का क्रम प्रासंगिक है।
स्टीफन

आपको परत सेट नहीं करनी चाहिए लेकिन फिर भी इसे प्राप्त कर सकते हैं। Objc.io/issues/14-mac/appkit-for-uikit-developers पर ColoredView
Clafou

80

यदि आप एक स्टोरीबोर्ड प्रेमी हैं, तो यहां एक तरीका है कि आपको कोड की किसी भी पंक्ति की आवश्यकता नहीं है

NSBoxNSView के लिए एक सबव्यू के रूप में जोड़ें और NSBox के फ्रेम को NSView के समान ही समायोजित करें।

स्टोरीबोर्ड या XIB में शीर्षक स्थिति को कोई नहीं बदल सकता है, बॉक्स प्रकार को कस्टम , बॉर्डर प्रकार को "कोई नहीं" और बॉर्डर का रंग जो भी आपको पसंद है।

यहाँ एक स्क्रीनशॉट है:

यहाँ छवि विवरण दर्ज करें

यह परिणाम है:

यहाँ छवि विवरण दर्ज करें


NSBox का उपयोग करना मेरे लिए बहुत अच्छा काम किया। परत-समर्थित दृश्य पर स्विच करने से Redraw समस्याएँ हो रही थीं, जबकि बॉक्स नहीं था।
हेनरिक

4
यह एक उत्कृष्ट और सरल उपाय है जो डॉक्स में होना चाहिए
UKDataGeek

इस रंग NSPopover हालांकि त्रिकोण?
रिबेना

मुझे केवल इस बात का पछतावा है कि मेरे पास इस उत्तर को देने के लिए एक उत्थान है।
ओरियन एल्जेनिल

33

यदि आप पहले हाँ में सेट करते हैं, तो आप सीधे लेयर बैकग्राउंड में फेरबदल कर सकते हैं।

[self.view setWantsLayer:YES];
[self.view.layer setBackgroundColor:[[NSColor whiteColor] CGColor]];

26

सोचें कि मुझे यह कैसे करना है:

- (void)drawRect:(NSRect)dirtyRect {
    // Fill in background Color
    CGContextRef context = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort];
    CGContextSetRGBFillColor(context, 0.227,0.251,0.337,0.8);
    CGContextFillRect(context, NSRectToCGRect(dirtyRect));
}

धन्यवाद। मुझे गंदी किरण को CGRect में बदलने की आवश्यकता थी। अंतिम पंक्ति को Ammended CGContextFillRect(context, NSRectToCGRect(dirtyRect));कर सकते हैं अपने जवाब को संपादित?
रॉस

1
वे टोल फ्री
ब्रिजिड हुआ करते थे

6
64-बिट या iOS के लिए निर्माण करते समय या 64-बिट की तरह 32-बिट का निर्माण करते समय, NSRect CGRect कहने का एक और तरीका है। यदि नहीं, हालांकि, ये स्वतंत्र संरचनाएं हैं, और भले ही वे एक ही सदस्यों से मिलकर हों, तो वे कभी भी "टोल-फ्री-ब्रिज" नहीं हो सकते हैं क्योंकि यह केवल वस्तुओं के संदर्भ में एक शब्द है ("आईएए" सूचक) और पॉइंटर्स का उपयोग करते हुए पास हो जाते हैं), लेकिन जेनेरिक संरचनाओं के लिए नहीं।
राफेल श्विकर्ट

अतिरिक्त ड्रा समय में ड्रॉअर रिजल्ट का उपयोग करना, आदि। 10.8 और उसके बाद कायर एक बेहतर समाधान है।
टॉम एंडरसन

22

मैं इन सभी उत्तरों से गुज़रा और उनमें से किसी ने भी मेरे लिए दुर्भाग्य से काम नहीं किया। हालाँकि, मुझे यह बेहद सरल तरीका लगा, खोज के लगभग एक घंटे के बाद:)

myView.layer.backgroundColor = CGColorCreateGenericRGB(0, 0, 0, 0.9);

8
ध्यान दें कि NSViews में हमेशा एक परत नहीं होती है, जिस स्थिति में यह कुछ भी नहीं करता है। Ioretoparisi का जवाब देखें।
कालू

3
मैंने इस कोड को अपने कंट्रोलर के देखने के तरीके में (self.myCustomView के लिए) करने में बहुत समय बिताया। मुझे लगा कि आपको इसके बजाय viewWillAppear विधि का उपयोग करना चाहिए।
सर्फराइड

21

संपादन / अद्यतन: Xcode 8.3.1 • स्विफ्ट 3.1

extension NSView {
    var backgroundColor: NSColor? {
        get {
            guard let color = layer?.backgroundColor else { return nil }
            return NSColor(cgColor: color)
        }
        set {
            wantsLayer = true
            layer?.backgroundColor = newValue?.cgColor
        }
    }
}

उपयोग:

let myView = NSView(frame: NSRect(x: 0, y: 0, width: 100, height: 100))
print(myView.backgroundColor ?? "none")     //  NSView's background hasn't been set yet = nil
myView.backgroundColor = .red               // set NSView's background color to red color
print(myView.backgroundColor ?? "none")
view.addSubview(myView)

मुझे लगता है कि यह सबसे साफ समाधान है, लेकिन इस बयान के बारे में चिंतित हूं कि ओबजियो इन लोगों को यहां बनाया गया है: objc.io/issues/14-mac/appkit-for-uikit-developers - "... आपको बातचीत करने की कोशिश नहीं करनी चाहिए सीधे परतों के साथ, जैसा कि AppKit उन परतों का मालिक है। " मुझे यकीन नहीं है कि क्या गलत हो सकता है। किसी भी तरह से, मैं इस समाधान को अपने कोड में अपना रहा हूं।
केविन स्लीच

7

सबसे अच्छा उपाय :

- (id)initWithFrame:(NSRect)frame
{
    self = [super initWithFrame:frame];
    if (self)
    {
        self.wantsLayer = YES;
    }
    return self;
}

- (void)awakeFromNib
{
    float r = (rand() % 255) / 255.0f;
    float g = (rand() % 255) / 255.0f;
    float b = (rand() % 255) / 255.0f;

    if(self.layer)
    {
        CGColorRef color = CGColorCreateGenericRGB(r, g, b, 1.0f);
        self.layer.backgroundColor = color;
        CGColorRelease(color);
    }
}

हेहे। यह काम करेगा यदि आप हर बार लॉन्च होने पर एक यादृच्छिक पृष्ठभूमि का रंग पसंद करते हैं, हालांकि थोड़ा और अधिक जटिल है तो ड्रॉ
रूट

: यदि यह एक बीजी रंग ड्राइंग का मामला है तो क्या अधिभावी के लिए आवश्यक है "drawRect"
नागराज

हाँ, शीर्ष उत्तर stackoverflow.com/a/2962882/285694 उस प्रतिक्रिया देता है। मेरे प्रश्न को वास्तव में एक अल्फा चैनल की आवश्यकता है, इसलिए मैंने इसे एक चेक दिया - stackoverflow.com/a/2962839/285694 - तकनीकी रूप से यह प्रश्न एक अल्फा चैनल के साथ NSView पर पृष्ठभूमि सेट करने के बारे में है (जैसे आप NSWindow के साथ कर सकते हैं) - लेकिन मुझे लगता है कि बहुत से लोग सिर्फ रंग सेट करने के तरीके की तलाश में यहां आते हैं (इस प्रकार पहला उत्तर अधिक लोकप्रिय है)।
बैडपिरेट

6

स्विफ्ट में:

override func drawRect(dirtyRect: NSRect) {

    NSColor.greenColor().setFill()
    NSRectFill(dirtyRect)

    super.drawRect(dirtyRect)
}

5

NSBox का उपयोग करें, जो NSView का एक उपवर्ग है, जिससे हम आसानी से स्टाइल कर सकते हैं

स्विफ्ट 3

let box = NSBox()
box.boxType = .custom
box.fillColor = NSColor.red
box.cornerRadius = 5

NSBox NSPopover के मामले में मदद नहीं करता है क्योंकि इसमें त्रिभुज भाग भी होता है।
अनघशर्मा

5

सबसे आसान तरीका शक के बिना, भी रंग सेट आस्तियों के साथ संगत:

स्विफ्ट :

view.setValue(NSColor.white, forKey: "backgroundColor")

उद्देश्य-सी :

[view setValue: NSColor.whiteColor forKey: "backgroundColor"];

इंटरफ़ेस बिल्डर :

backgroundColorइंटरफ़ेस बिल्डर में एक उपयोगकर्ता परिभाषित विशेषता जोड़ें , प्रकार की NSColor


यह अनैच्छिक व्यवहार पर निर्भर करता है और यदि आप अभी भी AppKit के भविष्य के संस्करणों में काम करना चाहते हैं तो इसे टाला जाना चाहिए।
nschmidt

3

मैंने निम्नलिखित परीक्षण किया और यह मेरे लिए काम किया (स्विफ्ट में):

view.wantsLayer = true
view.layer?.backgroundColor = NSColor.blackColor().colorWithAlphaComponent(0.5).CGColor

क्या आपने ऐसा करने के बाद आपके ऊपर एक छवि डाली थी? या क्या आपने NSImageView के बजाय NSView का उपयोग किया है?
JustColbs

3

स्विफ्ट 3 में, आप इसे करने के लिए एक एक्सटेंशन बना सकते हैं:

extension NSView {
    func setBackgroundColor(_ color: NSColor) {
        wantsLayer = true
        layer?.backgroundColor = color.cgColor
    }
}

// how to use
btn.setBackgroundColor(NSColor.gray)

1

RMSkinnedView पर एक नज़र है । आप इंटरफ़ेस बिल्डर के भीतर से NSView की पृष्ठभूमि का रंग सेट कर सकते हैं।


1

स्विफ्ट में आप NSView को सब्जेक्ट कर सकते हैं और ऐसा कर सकते हैं

class MyView:NSView {
    required init?(coder: NSCoder) {
        super.init(coder: coder);

        self.wantsLayer = true;
        self.layer?.backgroundColor = NSColor.redColor().CGColor;
    }
}

1
स्विफ्ट ४.२ Xcode १० सेल्फ। लेयर;? बैकग्राउंडरकलर = NSColor.red.cgColor
brian.clear

1

बस छोटा पुन: प्रयोज्य वर्ग (स्विफ्ट 4.1)

class View: NSView {

   var backgroundColor: NSColor?

   convenience init() {
      self.init(frame: NSRect())
   }

   override func draw(_ dirtyRect: NSRect) {
      if let backgroundColor = backgroundColor {
         backgroundColor.setFill()
         dirtyRect.fill()
      } else {
         super.draw(dirtyRect)
      }
   }
}

// Usage
let view = View()
view.backgroundColor = .white

1

बस backgroundColorपरत पर सेट (दृश्य परत समर्थित बनाने के बाद)।

view.wantsLayer = true
view.layer?.backgroundColor = CGColor.white

0

यह अनुप्रयोग के चलने के दौरान सिस्टमव्यापी उपस्थिति (अंधेरे मोड को चालू या बंद करना) बदलने का समर्थन करता है। आप इंटरफ़ेस बिल्डर में पृष्ठभूमि का रंग भी सेट कर सकते हैं, यदि आप पहले दृश्य के वर्ग को BackgroundColorView पर सेट करते हैं।


class BackgroundColorView: NSView {
    @IBInspectable var backgroundColor: NSColor? {
        didSet { needsDisplay = true }
    }

    override init(frame frameRect: NSRect) {
        super.init(frame: frameRect)
        wantsLayer = true
    }

    required init?(coder decoder: NSCoder) {
        super.init(coder: decoder)
        wantsLayer = true
    }

    override var wantsUpdateLayer: Bool { return true }

    override func updateLayer() {
        layer?.backgroundColor = backgroundColor?.cgColor
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.