Is there a standard way to have NSAlert conditionally close the window it is attached to?
I'm writing a super cool app with a preferences panel. If a user opens the preferences panel, makes a change to her preferences, and then closes the panel without saving thos开发者_运维技巧e changes, she will be greeted by an NSAlert informing her of the dire consequences. The NSAlert sheet has two buttons, "OK" and "Cancel". If the user presses "OK", then the sheet and the prefs panel should close. If the user presses "Cancel", then the sheet should close, but not the prefs panel.
Here's a simplified version of the code in question:
def windowShouldClose
window_will_close = true
unless self.user_is_aware_of_unsaved_changes
window_will_close = false
alert = make_appropriate_NSAlert # this method returns an NSAlert
alert.beginSheetModalForWindow(self.window,
modalDelegate: self,
didEndSelector: :'userShouldBeAware:returnCode:contextInfo:',
contextInfo: nil)
end
window_will_close
end
def userShouldBeAware(alert, returnCode:returnCode, contextInfo:contextInfo)
if returnCode == NSAlertFirstButtonReturn
self.user_is_aware_of_unsaved_changes = true
end
end
def windowDidEndSheet(notification)
self.window.performClose(self) if self.user_is_aware_of_unsaved_changes
end
I believe that I have made my super cool app perform the necessary duties, but I am concerned that this is not the way Apple intended or would recommend for me to implement this feature. It feels like a hack, and I was nowhere told explicitly that this is the way to do it. I tried a number of things before stumbling upon this solution.
I would like to make model mac apps. Is there some patten or document that goes into more detail about this? I have read Apple's documentation for the NSAlert class and their article on Sheet Programming Topics.
Thanks!
First off, according to the HIG, preference panes should not ask to cancel or confirm. Just auto-save whenever the user changes something. For reference, see how iTunes handles its preferences.
If you do want a save dialog, here's what I do. It can come in handy for when the user closes the app window and there's things to save. I use a drawer. That's a panel that I store in my MainMenu .nib file. Then I make it available as instance variable doneWindow, all using InterfaceBuilder and some clicking. Some more clicking in InterfaceBuilder registers the following two methods to be invoked at the appropriate events.
def showSaveDialog
NSApp.beginSheet( doneWindow,
modalForWindow: mainWindow,
modalDelegate: self,
didEndSelector: "didEndSheet:returnCode:contextInfo:".to_sym,
contextInfo: nil)
end
def save(bla)
NSApp.endSheet doneWindow
Pomodoro.new(:text => doneText).save
notifyLabelUpdate
end
def didEndSheet(bla, returnCode: aCode, contextInfo: bla3)
doneWindow.orderOut self
end
Note that the guide on sheets that you point to is the most confusing guide I've seen anywhere on the Apple documentation.
精彩评论