Каков наилучший способ запомнить позицию Windows между нагрузками приложения с использованием Obj-C? Я использую Interface Builder для интерфейса, возможно ли это сделать с привязками.
Каков рекомендуемый метод? Спасибо.
Каков наилучший способ запомнить позицию Windows между нагрузками приложения с использованием Obj-C? Я использую Interface Builder для интерфейса, возможно ли это сделать с привязками.
Каков рекомендуемый метод? Спасибо.
Поместите имя, уникальное для этого окна (например, "MainWindow" или "PrefsWindow" ) в поле "Автосохранение" в разделе "Атрибуты в построителе интерфейса". Затем он автоматически сохранит свое местоположение в пользовательских настройках по умолчанию.
Чтобы автоматически задать имя автосохранения, используйте -setFrameAutosaveName:
. Вы можете сделать это, если у вас есть приложение на основе документов или какая-либо другая ситуация, когда нет смысла устанавливать имя автосохранения в IB.
В Swift:
class MainWindowController : NSWindowController {
override func windowDidLoad() {
shouldCascadeWindows = false
window?.setFrameAutosaveName("MainWindow")
super.windowDidLoad()
}
В соответствии с документом, чтобы сохранить положение окна:
NSWindow *window = // the window in question
[[window windowController] setShouldCascadeWindows:NO]; // Tell the controller to not cascade its windows.
[window setFrameAutosaveName:[window representedFilename]]; // Specify the autosave name for the window.
Я пробовал все решения. Он может сохранять только положение, а не размер. Поэтому мы должны сделать это вручную. Вот как я это делаю в своем приложении GifCapture https://github.com/onmyway133/GifCapture
class MainWindowController: NSWindowController, NSWindowDelegate {
let key = "GifCaptureFrameKey"
override func windowDidLoad() {
super.windowDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(windowWillClose(_:)), name: Notification.Name.NSWindowWillClose, object: nil)
}
override func awakeFromNib() {
super.awakeFromNib()
guard let data = UserDefaults.standard.data(forKey: key),
let frame = NSKeyedUnarchiver.unarchiveObject(with: data) as? NSRect else {
return
}
window?.setFrame(frame, display: true)
}
func windowWillClose(_ notification: Notification) {
guard let frame = window?.frame else {
return
}
let data = NSKeyedArchiver.archivedData(withRootObject: frame)
UserDefaults.standard.set(data, forKey: key)
}
}
Чтобы восстановить окно, вы можете установить идентификатор восстановления в Interface Builder. Это будет использоваться как часть ключа, под которым кадр хранится в NSUserDefaults. - но это не всегда (всегда) работает для меня.
NSWindow
имеет setFrameUsingName(_:)
и т.д., чтобы настроить это, например, @BadmintonCat написал, и вы также можете сериализовать позицию окна вручную, если это не сработает.
Простейшим решением в моем приложении было использование свойства NSWindowController.windowFrameAutosaveName
и установка его в нечто в awakeFromNib(_:)
. Эта единственная строка повлияла на загрузку и сохранение.
Устали от Apple AutoSave и IB BS, которые иногда работают, а иногда не работают и зависят от настроек флагов в System Prefs бла-бла-бла. Просто сделайте это, и он ВСЕГДА РАБОТАЕТ и даже запоминает полноэкранное состояние пользователей!
-(void)applicationDidFinishLaunching:(NSNotification *)notification
{
[_window makeKeyAndOrderFront:self];
// Because Saving App Position and Size is FUBAR
NSString *savedAppFrame = [userSettings stringForKey:AppScreenSizeAndPosition];
NSRect frame;
if(savedAppFrame) {
frame = NSRectFromString(savedAppFrame);
[_window setFrame:frame display:YES];
}
else
[_window center];
// Because saving of app size and position on screen does not remember full screen
if([userSettings boolForKey:AppIsFullScreen])
[_window toggleFullScreen:self];
}
-(void)windowDidEnterFullScreen:(NSNotification *)notification
{
[userSettings setBool:YES forKey:AppIsFullScreen];
}
-(BOOL)windowShouldClose:(NSWindow *)sender
{
// Have to use this to set zoom state because exit full screen state always called on close
if(sender == _window) {
[userSettings setBool:(_window.isZoomed ? YES:NO) forKey:AppIsFullScreen];
}
return YES;
}
-(void)applicationWillTerminate:(NSNotification *)aNotification
{
[userSettings setObject:NSStringFromRect(_window.frame) forKey:AppScreenSizeAndPosition];
[userSettings synchronize];
}