2012-09-07 13 views
8

मुझे पता है कि यह एक लोकप्रिय सवाल नहीं होगा और कुछ लोगों को ऐसे ऐप्स पसंद नहीं हैं जिनके पास गैर-मानक रूप है, लेकिन यह मेरे आवेदन के लिए उपयोगी है।एनएसविंडो शीर्षक पाठ का रंग बदलना

क्या "मानक" गैर-निजी एपीआई तरीके से एनएसविंडो के टाइटलबार टेक्स्ट का रंग बदलना संभव है?

मुझे पता है कि अगर मैं निजी एपीआई (as mentioned in this answer) का उपयोग करता हूं, लेकिन मुझे लगता है कि निजी एपीआई के बिना ऐसा करना संभव है क्योंकि पिक्सेलमेटर ने इसे किया है और एमएएस से खारिज नहीं किया गया है। मुझे पता है कि इसे बनाना भी संभव है सीमाहीन खिड़की और सबकुछ खुद को चित्रित करना, लेकिन मुझे नहीं लगता कि पिक्सेलमेटर यह कैसे कर रहा है, क्योंकि उन्हें मानक एनएसविंडो टाइटलबार के साथ आने वाली सभी अतिरिक्त बिट्स मिलती हैं; ड्रैग करने योग्य आइकन, विंडो का नाम बदलें, दस्तावेज़ संशोधन के लिए ड्रॉपडाउन मेनू और । फुलस्क्रीन बटन

असल में, मैं setBackgroundColor का उपयोग कर एक काले रंग की खिड़की कर दिया है: लेकिन पाठ तब भी काला है, जो एक काले रंग की पृष्ठभूमि पर काम नहीं करता के रूप में आता

तो क्या कोई इसे करने का तरीका जानता है, या पिक्सेलमेटर यह कैसे कर रहा है?

+0

मैं इसे आज़माने के लिए बहुत आलसी हूं, लेकिन मुझे आश्चर्य है कि अगर आपको विंडो के सामग्री दृश्य मिलते हैं तो आपको क्या मिलेगा और इसे इसके पर्यवेक्षण के लिए कहा जाएगा। हो सकता है कि आप शून्य न हों, या हो सकता है कि आपको अन्य छिपी हुई चीज़ों वाला मूल दृश्य मिले। – JWWalker

+0

आपको एनएसटीहेम व्यू नामक एक निजी एनएसवी व्यू क्लास मिलता है। इसमें विंडो बंद करने, कम करने और बटन को अधिकतम करने के लिए कुछ और निजी दृश्य शामिल हैं, लेकिन मुझे नहीं लगता कि निजी एपीआई के बिना शीर्षक तक कैसे पहुंचे। – iain

+0

मैट गैलाघर द्वारा कस्टम विंडो के बारे में एक लेख है, आपको वहां कुछ जानकारी मिलनी चाहिए। http://www.cocoawithlove.com/2008/12/drawing-custom-window-on-mac-os-x.html – Michael

उत्तर

0

आप इसे कुछ निजी एपीआई का उपयोग करके अपने प्रश्न में टिप्पणियों में उल्लिखित के रूप में हल कर सकते हैं - हालांकि, आप ऐपस्टोर में उस ऐप को सबमिट करने में सक्षम नहीं होंगे।

अन्य समाधान [[myWindow contentView] superview] प्राप्त करना है - जो आपको उपरोक्त NSThemeView उदाहरण प्राप्त करता है। आपको बस इतना करना है कि एनएसटीक्स्टफिल्ड के किसी भी उदाहरण के लिए व्यू के सबव्यू (वास्तव में फ्रेम व्यू कहा जाता है) सबव्यूव्स को खोजना और उनको संशोधित करना है। ध्यान दें कि इन निजी विचारों का पदानुक्रम ओएस एक्स की प्रत्येक रिलीज के साथ बदल सकता है, संभावित रूप से आपके कोड को ब्रोक कर रहा है।

शायद सबसे अच्छा समाधान उपवर्ग के लिए (केवल उपवर्ग, कोई अन्य अनुकूलन) NSWindow और -title और -setTitle: तरीकों को लागू है - आप ([super setTitle:@""] फोन करके) @"" करने के लिए वास्तविक शीर्षक सेट करते हैं और उसके बाद जगह, प्रत्येक विंडो के लिए अपने एक स्वयं, प्रोग्रामेटिक रूप से बनाने, NSTextField फ्रेम दृश्य में उदाहरण (यानी [[[self contentView] superview] addSubview:myTextField], जहां myTextField पाठ क्षेत्र। आप सटीक स्थान, क्षेत्र के आदि यह पता लगाने की जरूरत है, लेकिन यह सबसे आसान हिस्सा है।

1

यहाँ है स्विफ्ट में समाधान। देर हो चुकी है और मैं थक गया हूं इसलिए यह संभवतः इष्टतम नहीं है लेकिन यह काम करता है।

सबसे पहले, एक विशिष्ट दृश्य को छोड़ने के विकल्प के साथ, पदानुक्रम के भीतर एक दृश्य खोजने के लिए यहां एक फ़ंक्शन है। (जो उपयोगी है अगर हम window.contentView.superview.subviews के माध्यम से खोज जा रहे हैं और हम contentView में अपने खुद के विचारों को अनदेखा करना चाहते)

func findViewInSubview(subviews: [NSView], #ignoreView: NSView, test: (NSView) -> Bool) -> NSView? { 
    for v in subviews { 
     if test(v) { 
      return v 
     } else if v != ignoreView { 
      if let found = findViewInSubview(v.subviews as [NSView], ignoreView: ignoreView, test) { 
       return found 
      } 
     } 
    } 
    return nil 
} 

और यहाँ आप इसे कैसे एक NSViewController उपवर्ग से प्रयोग करेंगे, उदाहरण के लिए है। ध्यान दें कि खिड़की दिखाई देने पर आपको इसे करने की ज़रूरत है, इसलिए आप इसे viewDidLoad में नहीं कर सकते हैं।

override func viewDidAppear() { 
    if let windowContentView = view.window?.contentView as? NSView { 
     if let windowContentSuperView = windowContentView.superview { 
      let titleView = findViewInSubview(windowContentSuperView.subviews as [NSView], ignoreView: windowContentView) { (view) -> Bool in 
       // We find the title by looking for an NSTextField. You may 
       // want to make this test more strict and for example also 
       // check for the title string value to be sure. 
       return view is NSTextField 
      } 
      if let titleView = titleView as? NSTextField { 
       titleView.attributedStringValue = NSAttributedString(string: "Hello", attributes: [NSForegroundColorAttributeName: NSColor.redColor()]) 
      } 
     } 
    } 
} 

ध्यान दें कि आप आग से खेल रहे हैं। इस तरह के आंतरिक कारण किसी कारण से अनिर्दिष्ट हैं।

+0

यह मेरे लिए काम करता है, हालांकि ऐसा लगता है कि यह टेक्स्ट को दो बार खींचता है। पहला पाठ सामान्य रूप से तैयार किया जाता है, जैसा कि वांछित था, लेकिन दूसरा एक थोड़ा सा बंद है। यह वास्तव में एक अजीब लग रहा है। इसे हल करने के बारे में कोई विचार? [लिंक] (http://imgur.com/oYaoAeJ) –

8

ओएस एक्स 10 के बाद से।10 यह NSAppearanceNameVibrantDark

window.appearance = NSAppearance(named:NSAppearanceNameVibrantDark) 

के लिए विंडो के स्वरूप बदलने के लिए पर्याप्त होना चाहिए विचार के बाद से जवाब आप पा सकते हैं के सबसे पुराने हो चुके हैं उल्लेख करने के लिए लायक है।

#import <objc/runtime.h> 

@interface SOWindow : NSWindow 
@end 

@interface SOWindowFrameOverrides : NSView 
@end 

@implementation SOWindow 

+ (void)load 
{ 
    SEL selector = NSSelectorFromString(@"_currentTitleColor"); 
    SEL originalSelector = NSSelectorFromString(@"_original_currentTitleColor"); 
    Class frameClass = NSClassFromString(@"NSThemeFrame"); 

    Method m = class_getInstanceMethod(frameClass, selector); 
    Method m2 = class_getInstanceMethod([SOWindowFrameOverrides class], selector); 
    class_addMethod(frameClass, originalSelector, method_getImplementation(m), method_getTypeEncoding(m)); 
    method_exchangeImplementations(m, m2); 
} 

@end 

@implementation SOWindowFrameOverrides 

- (NSColor *)_currentTitleColor 
{ 
    if ([self.window isKindOfClass:[SOWindow class]]) { 
     return [NSColor redColor]; 
    } else { 
     return [self _original_currentTitleColor]; 
    } 
} 

- (NSColor *)_original_currentTitleColor 
{ 
    // will be filled in at runtime 
    return nil; 
} 

@end 

दृश्य पदानुक्रम Yosemite को मावेरिक्स से बहुत कुछ बदल गया है, _currentTitleColor एक लंबे समय के लिए एपीआई में रहा है और शायद पास में परिवर्तन नहीं होगा:

+0

पैनलों के साथ काम नहीं कर रहा है ... "अपरिचित चयनकर्ता '_backstoppedByDefaultAppearance'" –

+0

NSAppearanceNameVibrantDark बहुत अच्छा लग रहा है, लेकिन ऐसा लगता है कि मेरे ओपनजीएल आधारित ऐप में समस्याएं उत्पन्न होती हैं ... ऐसा प्रतीत होता है अर्द्ध पारदर्शी विंडो बार बनाने के लिए, और CoreAnimation बकवास का उपयोग करने लगता है। मैं सिर्फ एक साधारण अंधेरे एनएसपीपीरेंस चाहता हूं बिना फ्रिल्स! –

0

इस तरह से मैं यह करना है भविष्य। यहां तक ​​कि कठिन तरीका स्विजलिंग यह करने का एक हैकी तरीका है, मुझे लगता है कि दृश्य पदानुक्रम को पार करने से यह अधिक सुरुचिपूर्ण है, लेकिन यह सिर्फ मुझे है।

आप शीर्षक अनुकूलित करने के लिए आगे भी चाहते हैं, आप _titleTextFieldNSThemeFrame पर एक कस्टमाइज़ पाठ क्षेत्र वापस जाने के लिए ओवरराइड कर सकते हैं (मैं यह इस्तेमाल किया है मेरी F3X परियोजना पर backgroundStyle बदलने के लिए)।