Подтвердить что ты не робот

Как я могу легко сохранить размер окна и положение позиции с помощью Obj-C?

Каков наилучший способ запомнить позицию Windows между нагрузками приложения с использованием Obj-C? Я использую Interface Builder для интерфейса, возможно ли это сделать с привязками.

Каков рекомендуемый метод? Спасибо.

4b9b3361

Ответ 1

Поместите имя, уникальное для этого окна (например, "MainWindow" или "PrefsWindow" ) в поле "Автосохранение" в разделе "Атрибуты в построителе интерфейса". Затем он автоматически сохранит свое местоположение в пользовательских настройках по умолчанию.

Чтобы автоматически задать имя автосохранения, используйте -setFrameAutosaveName:. Вы можете сделать это, если у вас есть приложение на основе документов или какая-либо другая ситуация, когда нет смысла устанавливать имя автосохранения в IB.

Ссылка на документацию.

Ответ 2

В Swift:

class MainWindowController : NSWindowController {
    override func windowDidLoad() {
        shouldCascadeWindows = false
        window?.setFrameAutosaveName("MainWindow")

        super.windowDidLoad()
    }

Ответ 3

В соответствии с документом, чтобы сохранить положение окна:

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.

Ответ 4

Я пробовал все решения. Он может сохранять только положение, а не размер. Поэтому мы должны сделать это вручную. Вот как я это делаю в своем приложении 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)
  }
}

Ответ 5

Чтобы восстановить окно, вы можете установить идентификатор восстановления в Interface Builder. Это будет использоваться как часть ключа, под которым кадр хранится в NSUserDefaults. - но это не всегда (всегда) работает для меня.

NSWindow имеет setFrameUsingName(_:) и т.д., чтобы настроить это, например, @BadmintonCat написал, и вы также можете сериализовать позицию окна вручную, если это не сработает.

Простейшим решением в моем приложении было использование свойства NSWindowController.windowFrameAutosaveName и установка его в нечто в awakeFromNib(_:). Эта единственная строка повлияла на загрузку и сохранение.

Ответ 6

Устали от 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];
}