33 votes

Restauration de l'état de l'interface utilisateur NSViewController

Résumé:

Quelle est la bonne façon de sauvegarder/restaurer l'état d'un NSSearchField mon NSViewController à l'aide de l'interface utilisateur intégrée mécanisme de conservation de Cacao?

Détails:

Je suis en train de travailler sur mon premier macOS app et je vais avoir un peu de mal avec la restauration de l'état de mon interface utilisateur. Jusqu'à présent, je avoir de travail au point où l' encodeRestorableState(with:) et restoreState(with:) méthodes sont appelées dans mon NSViewController sous-classe.

J'ai un NSSearchField de mon point de vue contrôleur et je veux sauver/restaurer l'état du champ de recherche, y compris son texte, toute sélection, la position du curseur, et s'il est actuellement le focus ou pas.

Si j'utilise le code suivant, le texte est correctement enregistré et restauré:

override func encodeRestorableState(with coder: NSCoder) {
    super.encodeRestorableState(with: coder)

    coder.encode(searchField.stringValue, forKey: "searchText")
}

override func restoreState(with coder: NSCoder) {
    super.restoreState(with: coder)

    if let searchText = coder.decodeObject(forKey: "searchText") as? String {
        searchField.stringValue = searchText
    }
}

Évidemment, je peux ajouter plus de code pour sauvegarder/restaurer le champ de recherche, à la sélection et à la position du curseur, etc.

Ma vraie question est, est-il mieux, de la bonne, plus de moyen automatique pour enregistrer et restaurer le champ de recherche de l'état? Ou est-il nécessaire que j'écris mon propre code pour chaque attribut du champ de recherche, je tiens à le sauver?

J'ai essayé d'utiliser:

searchField.encodeRestorableState(with: coder)

et:

searchField.restoreState(with: coder)

dans les deux méthodes ci-dessus, mais ce n'est pas le résultat de tout ce qui apparaît dans le champ de recherche lors de mon application a été redémarré.

J'ai également mis en œuvre:

override class func restorableStateKeyPaths() -> [String] {
    var keys = super.restorableStateKeyPaths()
    keys.append("searchField.stringValue")

    return keys
}

"searchField" est le nom de l' NSTextField prise de la propriété de mon point de vue contrôleur. Cette méthode est appelée lorsque mon application est lancée, mais le texte n'a pas été restauré dans le champ de recherche.

Ce point de vue contrôleur est créé à partir d'un storyboard. Le point de vue du contrôleur identifier est réglé. Le champ de recherche de l' identifier est définie ainsi. Cette vue-contrôleur est un enfant-vue-contrôleur d'un autre point de vue contrôleur.

J'ai lu à travers l' Interface Utilisateur de la Préservation de la section "Le Noyau de la Conception d'Application du document", mais il n'est pas clair sur la façon dont une vue-contrôleur les vues sont à sauver/restaurer et comment cela est-il automatique ou manuelle.

Soutenir OSX et 10.11 10.12. Objective-C ou Swift dans toutes les réponses, c'est très bien.

1voto

Gigantic Points 4447

Pour atteindre l'effet susmentionné créons NSSearchField et une classe personnalisée nommée RestoredWindow contenant seulement une propriété:

import Cocoa

class RestoredWindow: NSWindow {

    override class var restorableStateKeyPaths: [String] {
        return ["self.contentViewController.searchField.stringValue"]
    }
}

Attribuer cette classe personnalisée à la Fenêtre Contrôleur dans l'Identité de l'Inspecteur.

Ensuite, nous allons lier searchField.stringValue de la propriété d' ViewController en Value de la section de Liaisons Inspecteur.

import Cocoa

class ViewController: NSViewController {

    @IBOutlet weak var searchField: NSSearchField!

    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

Après cela, assurez-vous que vous n'avez pas coché Close windows when quitting an app option dans votre System Preferences -> General tab.

Maintenant, le texte entré en NSSearchField restauré après avoir cessé de fumer et de lancer l'application à nouveau.

P. S.

J'ai essayé de la même manière que vous, mais a échoué aussi. Cette approche ne fonctionne pas pour moi:

override func encodeRestorableState(with coder: NSCoder) {
    coder.encode(searchField.stringValue, forKey: "restore")
    super.encodeRestorableState(with: coder)
}

override func restoreState(with coder: NSCoder) {   
    if let state = coder.decodeObject(forKey: "restore") as? NSSearchField {
        searchField.stringValue = state
    }
    super.restoreState(with: coder)
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X