में एक सरल अनुप्रयोग-मॉडल संवाद को प्रदर्शित और प्रबंधित करने के लिए कैसे करें मुझे यकीन नहीं है कि मैं सही तरीके से काम कर रहा हूं, या यदि मेरे पास यह सब हैक हो गया है।कोको
मेरे पास कोको अनुप्रयोगों में एप्लिकेशन-मोडल संवाद के साथ काम करने के तरीके के बारे में सीखने के लिए मैंने वास्तव में एक सरल परीक्षण एप्लिकेशन (दस्तावेज़-आधारित नहीं) बनाया है।
एप्लिकेशन प्रोजेक्ट "TestModalDialog" के साथ, मेरे पास डिफ़ॉल्ट दृश्य और एक बटन "संवाद दिखाएं" के साथ एक साधारण MainMenu.xib है। मैंने TheDialog.xib नामक एक दूसरा XIB बनाया है जिसमें "रद्द करें" और "ठीक" बटन हैं। उस xib के मालिक के रूप में NSWindowController से लिया गया एक वर्ग है जिसे "TheDialogController" कहा जाता है; विंडो आउटलेट और प्रतिनिधि नियंत्रक से जुड़े हुए हैं।
मुख्य दृश्य पर "संवाद दिखाएं" का चयन संवाद लॉन्च करेगा। "रद्द करें" या "ठीक" का चयन संवाद को खारिज कर देगा। यहाँ बहुत सरल कोड है:
// TestModalDialogAppDelegate.h
// TestModalDialog
#import <Cocoa/Cocoa.h>
@class TheDialogController;
@interface TestModalDialogAppDelegate : NSObject <NSApplicationDelegate>
{
NSWindow *window;
TheDialogController* theDialogController;
}
@property (assign) IBOutlet NSWindow *window;
- (IBAction)showDialog:(id)sender;
@end
// TestModalDialogAppDelegate.m
// TestModalDialog
#import "TestModalDialogAppDelegate.h"
#import "TheDialogController.h"
@implementation TestModalDialogAppDelegate
@synthesize window;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
theDialogController= [[TheDialogController alloc] init];
}
- (void)dealloc
{
if(nil != theDialogController)
[theDialogController release];
[super dealloc];
}
- (IBAction)showDialog:(id)sender
{
if(nil == theDialogController)
{
NSAlert* alert= [NSAlert alertWithMessageText:@"Dialog Error" defaultButton:nil alternateButton:nil otherButton:nil informativeTextWithFormat:@"The dialog controller was not allocated."];
[alert runModal];
return;
}
NSInteger result= [NSApp runModalForWindow:[theDialogController window]];
// Do something with result....
}
@end
// TheDialogController.h
// TestModalDialog
#import <Cocoa/Cocoa.h>
@interface TheDialogController : NSWindowController
{
// BOOL userClickedCloseOrOk; // Removed based on answer.
// Should declare a common define - just being lazy.
NSInteger userClickedOk; // Added based on answer.
UInt16 timesShown;
}
- (IBAction)showWindow:(id)sender;
- (IBAction)closeDialog:(id)sender;
- (IBAction)okDialog:(id)sender;
//- (BOOL)windowShouldClose:(id)sender; // Removed based on answer.
- (void)windowWillClose:(NSNotification*)notification; // Added based on answer.
- (void)windowDidBecomeKey:(NSNotification*)notification; // To set title when modal.
@end
// TheDialogController.m
// TestModalDialog
#import "TheDialogController.h"
@implementation TheDialogController
- (id)init
{
self = [super initWithWindowNibName:@"TheDialog"];
userClickedOk= 0; // Added based on answer.
// userClickedCloseOrOk= FALSE; // Removed based on answer.
return self;
}
-(void)dealloc
{
// Do member cleanup if needed.
[super dealloc];
}
- (void)windowDidLoad
{
[super windowDidLoad];
// Initialize as needed....
[[self window] center]; // Center the window.
}
// Does not show with runModalForWindow.
- (IBAction)showWindow:(id)sender
{
// Just playing with the window title....
++timesShown;
NSString* newTitle= [NSString stringWithFormat:@"Shown %d Times", timesShown];
[[self window] setTitle:newTitle];
return [super showWindow:sender];
}
// This method no longer used for this solution based on the answer.
//- (BOOL)windowShouldClose:(id)sender
//{
// if(!userClickedCloseOrOk) // The user did not click one of our buttons.
// [NSApp abortModal];
// else
// userClickedCloseOrOk= FALSE; // Clear for next time.
//
// return TRUE;
//}
// Added based on answer.
- (void)windowWillClose:(NSNotification*)notification
{
[NSApp stopModalWithCode:userClickedOk];
userClickedOk= 0; // Reset for next time.
}
// Note - the title will update every time the window becomes key. To do the
// update only once per modal session, a flag can be added. There might be a better
// notification to catch.
- (void)windowDidBecomeKey:(NSNotification*)notification
{
++timesShown;
NSString* newTitle= [NSString stringWithFormat:@"Shown %d Times", timesShown];
[[self window] setTitle:newTitle];
}
- (IBAction)closeDialog:(id)sender
{
//userClickedCloseOrOk= TRUE; // Removed based on answer.
//[NSApp abortModal]; // Removed based on answer.
//[[self window] performClose:self]; // Removed based on answer.
[[self window] close]; // Know we want to close - based on answer.
}
- (IBAction)okDialog:(id)sender
{
userClickedOk= 1; // Added based on answer.
//userClickedCloseOrOk= TRUE; // Removed based on answer.
//[NSApp stopModal]; // Removed based on answer.
//[[self window] performClose:self]; // Removed based on answer.
[[self window] close]; // Know we want to close - based on answer.
}
@end
मैं साधन में समस्या आई - इससे पहले कि मैं userClickedCloseOrOk और परीक्षण में डाल दिया, उपयोगकर्ता बंद करें बटन (ऊपरी-बाएँ लाल डॉट) मारा है, संवाद को बंद होगा, लेकिन मोडल सत्र अभी भी चल रहा था।
मुझे एहसास है कि मैं संवाद के बंद होने के लिए बंद-बंद बटन छोड़ सकता हूं, लेकिन इसके साथ ही, मैंने उस परिदृश्य को पकड़ने के लिए एक अच्छा तरीका दिखाया है, या क्या कोई बेहतर तरीका है? या, क्या मैं शुरू करने में कुछ गलत कर रहा हूं, जो मेरे लिए उस समस्या को बनाता है?
किसी भी सलाह की सराहना की जाएगी।
नोट - मूल उदाहरण से कोड ने टिप्पणी के आधार पर कोड के साथ टिप्पणी की और प्रतिस्थापित किया। एक नया अधिसूचना हैंडलर भी जोड़ा।
क्या विंडोडिडबैककी से बेहतर तरीका है: या windowDidBecomeMain: यह जानने के लिए कि जब मॉड्यूल सत्र में विंडो प्रदर्शित होती है? मैं पूछता हूं क्योंकि मैं जानना चाहता हूं कि मोडल सत्र वास्तव में कब शुरू होता है। मैं हर बार खिड़की बना/नष्ट कर सकता हूं, और फिर विंडोडिडलोड का उपयोग कर सकता हूं, लेकिन यह बहुत ही कुशल प्रतीत नहीं होता है। मैं एक मॉड्यूल सत्र में दिखाने वाली खिड़की को बताने के लिए एक ध्वज में भी भेज सकता हूं, और इसे किसी अधिसूचना से प्रबंधित कर सकता हूं - फिर, यह एक हैक जैसा लगता है। या, क्या मुझे इसके बजाय चादर का उपयोग करना चाहिए? – GTAE86