2012-09-18 14 views
9

मैंने कस्टम एनएसबूटन आकर्षित करने का प्रयास किया है, लेकिन ऐसा लगता है कि मैं यहां पहिया को फिर से शुरू कर रहा हूं। क्या बंद करने, कम करने और ज़ूम बटन के लिए उपयोग की जाने वाली डिफ़ॉल्ट छवियों को प्रतिस्थापित करने का कोई तरीका है?कस्टम विंडो नियंत्रण कैसे बनाएं (बंद करें, न्यूनतम करें, और ज़ूम बटन)

कई क्षुधा पहले से ही यह कार्य करें:

  • OSX 10.8 के अनुस्मारक एप्लिकेशन (वे गहरे भूरे रंग जब खिड़की, कुंजी नहीं है दिखाई बनाम सबसे दिखाई हल्के भूरे रंग)
  • Tweetbot (सभी बटन पूरी तरह से कस्टम देखो)

और जानकारी:

मैं ऐसे standardWindowButton:NSWindowCloseButton के रूप में सिस्टम डिफ़ॉल्ट उत्पन्न कर सकते हैं। लेकिन वहां से setImage सेटर बटन की उपस्थिति को नहीं बदलता है।

उत्तर

26

संपादित: जब से मैं यह लिखा, INAppStoreINWindowButton के साथ ऐसा करना एक बहुत अच्छा तरीका लागू किया है। यदि आप वहां ड्रैग और ड्रॉप समाधान की तलाश में हैं, तो नीचे दिया गया कोड अभी भी आपको स्वयं को लागू करने में मदद करेगा।


तो मुझे standardWindowButton एस को बदलने का कोई तरीका नहीं मिला। यहां एक पैदल यात्रा है कि मैंने अपने बटन कैसे बनाए।

नोट: 4 में कहा गया हैं बटन हो सकता है में

  • विंडो निष्क्रिय Window Inactive Controls
  • विंडो सक्रिय - सामान्य Window Active Normal Controls
  • विंडो सक्रिय - मंडराना Window Active Hover Controls
  • विंडो सक्रिय - प्रेस Window Active Press Controls

walkthrough पर!

चरण 1: पहले से मौजूद बटन छुपाएं

NSButton *windowButton = [self standardWindowButton:NSWindowCloseButton]; 
[windowButton setHidden:YES]; 
windowButton = [self standardWindowButton:NSWindowMiniaturizeButton]; 
[windowButton setHidden:YES]; 
windowButton = [self standardWindowButton:NSWindowZoomButton]; 
[windowButton setHidden:YES]; 

चरण 2: सेटअप इंटरफ़ेस बिल्डर में दृश्य

आप पर बटन अपने मंडराना करने के लिए सभी परिवर्तन मंडराना पर ध्यान देंगे राज्य, इसलिए हमें होवर लेने के लिए एक कंटेनर दृश्य की आवश्यकता है।

  • 54px चौड़ा x 16px लंबा होने के लिए एक कंटेनर दृश्य बनाएं।
  • कंटेनर व्यू के अंदर 3 स्क्वायर स्टाइल NSButton एस, प्रत्येक 14px चौड़ा x 16px लंबा बनाएं।
  • बटनों को बाहर निकालें ताकि बीच में 6px अंतराल हो।

सेटअप बटन

  • गुण निरीक्षक में, खिड़की सक्रिय-सामान्य छवि के लिए प्रत्येक बटन के लिए Image गुण सेट।
  • विंडो-सक्रिय-प्रेस छवि पर Alternate छवि गुण सेट करें।
  • Bordered बंद करें।
  • Type से Momentary Change पर सेट करें।
  • प्रत्येक बटन के लिए close, minimize या zoom को पहचानकर्ता सेट

चरण 3 (नीचे आप यह कैसे उपयोग कर सकते हैं NSButton उपवर्ग सरल बनाने के लिए देखेंगे): कंटेनर दृश्य उपवर्ग & बटन

कंटेनर:

एक नई फ़ाइल बनाएं, उपवर्ग NSView। यहां हम बटन को बताने के लिए अधिसूचना केंद्र का उपयोग करने जा रहे हैं जब उन्हें अपने होवर राज्य में स्विच करना चाहिए।

HMTrafficLightButtonsContainer.m

// Tells the view to pick up the hover event 
- (void)viewDidMoveToWindow { 
    [self addTrackingRect:[self bounds] 
        owner:self 
       userData:nil 
      assumeInside:NO]; 
} 

// When the mouse enters/exits we send out these notifications 
- (void)mouseEntered:(NSEvent *)theEvent { 
    [[NSNotificationCenter defaultCenter] postNotificationName:@"HMTrafficButtonMouseEnter" object:self]; 
} 
- (void)mouseExited:(NSEvent *)theEvent { 
    [[NSNotificationCenter defaultCenter] postNotificationName:@"HMTrafficButtonMouseExit" object:self];   
} 

बटन:

एक नई फ़ाइल इस समय उपवर्ग NSButton बनाएँ,। यह समझाने के लिए थोड़ा और है इसलिए मैं बस सभी कोड पोस्ट करूंगा।

HMTrafficLightButton.m

@implementation HMTrafficLightButton { 
    NSImage *inactive; 
    NSImage *active; 
    NSImage *hover; 
    NSImage *press; 
    BOOL activeState; 
    BOOL hoverState; 
    BOOL pressedState; 
} 

-(id)initWithCoder:(NSCoder *)aDecoder { 
    self = [super initWithCoder:aDecoder]; 
    if (self) {   
     [self setup]; 
    } 
    return self; 
} 

- (id)initWithFrame:(NSRect)frameRect { 
    self = [super initWithFrame:frameRect]; 
    if (self) { 
     [self setup]; 
    } 
    return self; 
} 

- (void)setup { 
    // Setup images, we use the identifier to chose which image to load 
    active = [NSImage imageNamed:[NSString stringWithFormat:@"window-button-%@-active",self.identifier]]; 
    hover = [NSImage imageNamed:[NSString stringWithFormat:@"window-button-%@-hover",self.identifier]]; 
    press = [NSImage imageNamed:[NSString stringWithFormat:@"window-button-%@-press",self.identifier]]; 
    inactive = [NSImage imageNamed:@"window-button-all-inactive"]; 

    // Checks to see if window is active or inactive when the `init` is called 
    if ([self.window isMainWindow] && [[NSApplication sharedApplication] isActive]) { 
     [self setActiveState]; 
    } else { 
     [self setInactiveState]; 
    } 

    // Watch for hover notifications from the container view 
    // Also watches for notifications for when the window 
    // becomes/resigns main 
    [[NSNotificationCenter defaultCenter] addObserver:self 
              selector:@selector(setActiveState) 
               name:NSWindowDidBecomeMainNotification object:nil]; 
    [[NSNotificationCenter defaultCenter] addObserver:self 
              selector:@selector(setInactiveState) 
               name:NSWindowDidResignMainNotification object:nil]; 
    [[NSNotificationCenter defaultCenter] addObserver:self 
              selector:@selector(hoverIn) 
               name:@"HMTrafficButtonMouseEnter" 
               object:nil]; 
    [[NSNotificationCenter defaultCenter] addObserver:self 
              selector:@selector(hoverOut) 
               name:@"HMTrafficButtonMouseExit" 
               object:nil]; 
} 

- (void)mouseDown:(NSEvent *)theEvent { 
    pressedState = YES; 
    hoverState = NO; 
    [super mouseDown:theEvent]; 
} 

- (void)mouseUp:(NSEvent *)theEvent { 
    pressedState = NO; 
    hoverState = YES; 
    [super mouseUp:theEvent]; 
} 

- (void)setActiveState { 
    activeState = YES; 
    if (hoverState) { 
     [self setImage:hover]; 
    } else { 
     [self setImage:active]; 
    } 
} 

- (void)setInactiveState { 
    activeState = NO; 
    [self setImage:inactive]; 
} 

- (void)hoverIn { 
    hoverState = YES; 
    [self setImage:hover]; 
} 

- (void)hoverOut { 
    hoverState = NO; 
    if (activeState) { 
     [self setImage:active]; 
    } else { 
     [self setImage:inactive]; 
    } 
} 

- (void)dealloc { 
    [[NSNotificationCenter defaultCenter] removeObserver:self]; 
} 

@end 

आईबी में कंटेनर को देखने के कस्टम वर्ग और है कि हम अभी बनाया उनके संबंधित वर्गों के लिए सभी 3 बटन निर्धारित किया है।

चरण 4: बटन कार्यों

इन विधियों दृश्य नियंत्रक से कहा जाता है, के रूप में सेट standardWindowButton s 'एक ही हैं। उन्हें आईबी में बटन से लिंक करें।

- (IBAction)clickCloseButton:(id)sender { 
    [self.view.window close]; 
} 
- (IBAction)clickMinimizeButton:(id)sender { 
    [self.view.window miniaturize:sender]; 
} 
- (IBAction)clickZoomButton:(id)sender { 
    [self.view.window zoom:sender]; 
} 

चरण 5: खिड़की

करने के लिए दृश्य जोड़े मैं खिड़की नियंत्रण के लिए एक अलग xib और देखने नियंत्रक सेटअप विशेष रूप से की है। दृश्य नियंत्रक HMWindowControlsController

(HMWindowControlsController*) windowControlsController = [[HMWindowControlsController alloc] initWithNibName:@"WindowControls" bundle:nil]; 
NSView *windowControlsView = windowControlsController.view; 
// Set the position of the window controls, the x is 7 px, the y will 
// depend on your titlebar height. 
windowControlsView.frame = NSMakeRect(7.0, 10.0, 54.0, 16.0); 
// Add to target view 
[targetView addSubview:windowControlsView]; 

आशा इस मदद करता है कहा जाता है। यह एक बहुत लंबी पोस्ट है, अगर आपको लगता है कि मैंने गलती की है या कुछ छोड़ दिया है तो कृपया मुझे बताएं।

+1

यह एक लंबी पोस्ट नहीं है, यह एक ** महान ** उत्तर है। भविष्य के संदर्भ के लिए बुकमार्क किया गया। – sosborn

+0

@ सोसबर्न धन्यवाद, प्रतिक्रिया की सराहना करें :) –

+0

यह पोस्ट एक्सेसिबिलिटी और प्रथम-माउस व्यवहार जैसे मुद्दों का इलाज नहीं करता है। ये सही पाने के लिए मुश्किल हैं ... सबसे अच्छी बात सिर्फ सिस्टम के बटन का उपयोग करना है! (ध्यान दें कि योसाइट के रूप में, टूलबार और विंडो शीर्षक बार को जोड़ा जा सकता है और विंडो बटन लंबवत केंद्रित होंगे।) – jtbandes

संबंधित मुद्दे