Comment ajouter une barre d'outils à une application macOS à l'aide de SwiftUI?

9

J'essaie d'ajouter une barre d'outils à l'intérieur de la barre de titre à une application macOS à l'aide de SwiftUI, quelque chose de similaire à ce qui est illustré ci-dessous.

Barre d'outils dans la barre de titre dans l'application macOS

Je ne suis pas en mesure de trouver un moyen d'y parvenir en utilisant SwiftUI. Actuellement, j'ai ma barre d'outils (qui a juste un champ de texte) dans ma vue, mais je veux la déplacer dans la barre de titre.

Mon code actuel:

struct TestView: View {
    var body: some View {
        VStack {
            TextField("Placeholder", text: .constant("")).padding()
            Spacer()
        }
    }
}

Donc, dans mon cas, j'ai besoin d'avoir le champ de texte à l'intérieur de la barre d'outils.

Bijoy Thangaraj
la source
Je parle de SwiftUI dans la cible macOS.
Bijoy Thangaraj
Non, le modificateur navigationBarTitle n'est pas disponible dans macOS SwiftUI.
Bijoy Thangaraj
La barre d'outils n'est pas prise en charge dans SwiftUI pour l'instant. Si vous en avez vraiment besoin (pourquoi?), Utilisez-en un d'AppKit, il est toujours là ... vraiment.
Asperi
@Asperi J'ai pu le faire - veuillez voir la réponse ci-dessous. Les barres d'outils (ou accessoires de la barre de titre) sont encore largement utilisées dans les applications macOS, n'est-ce pas?
Bijoy Thangaraj
@Asperi Pour utiliser celui d'AppKit, vouliez-vous utiliser NSViewRepresentable pour NSToolbar? Si c'est le cas, j'ai essayé cette méthode mais sans succès. Si vous avez une solution de cette façon, j'aimerais la vérifier.
Bijoy Thangaraj

Réponses:

4

Approche 1:

Cela se fait en ajoutant un accessoire de barre de titre. J'ai pu faire cela en modifiant le fichier AppDelegate.swift. J'ai dû appliquer un rembourrage bizarre pour que ça paraisse bien.

AppDelegate.swift

func applicationDidFinishLaunching(_ aNotification: Notification) {
        // Create the SwiftUI view that provides the window contents.
        let contentView = ContentView()

        // Create the titlebar accessory
        let titlebarAccessoryView = TitlebarAccessory().padding([.top, .leading, .trailing], 16.0).padding(.bottom,-8.0).edgesIgnoringSafeArea(.top)

        let accessoryHostingView = NSHostingView(rootView:titlebarAccessoryView)
        accessoryHostingView.frame.size = accessoryHostingView.fittingSize

        let titlebarAccessory = NSTitlebarAccessoryViewController()
        titlebarAccessory.view = accessoryHostingView       

        // Create the window and set the content view. 
        window = NSWindow(
            contentRect: NSRect(x: 0, y: 0, width: 480, height: 300),
            styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView],
            backing: .buffered, defer: false)
        window.center()
        window.setFrameAutosaveName("Main Window")

        // Add the titlebar accessory
        window.addTitlebarAccessoryViewController(titlebarAccessory)

        window.contentView = NSHostingView(rootView: contentView)
        window.makeKeyAndOrderFront(nil)
    }

TitlebarAccessory.swift

import SwiftUI

struct TitlebarAccessory: View {
    var body: some View {

        TextField("Placeholder", text: .constant(""))

    }
}

Résultat:

Contenu dans la barre d'outils macOS

Approche 2 (méthode alternative):

L'idée ici est de faire la partie de la barre d'outils en utilisant le storyboard et le reste de l'application en utilisant SwiftUI. Cela se fait en créant une nouvelle application avec storyboard comme interface utilisateur. Ensuite, allez dans le storyboard et supprimez le contrôleur de vue par défaut et ajoutez-en un nouveau NSHostingController. Connectez le contrôleur d'hébergement nouvellement ajouté à la fenêtre principale en définissant sa relation. Ajoutez votre barre d'outils à la fenêtre à l'aide du générateur d'interface.

Configuration du storyboard

Attachez une classe personnalisée à votre NSHostingControlleret chargez-y votre vue SwiftUI.

Exemple de code ci-dessous:

import Cocoa
import SwiftUI

class HostingController: NSHostingController<SwiftUIView> {

    @objc required dynamic init?(coder: NSCoder) {
        super.init(coder: coder, rootView: SwiftUIView())       

    }

}

L'utilisation de cette approche vous donne également la possibilité de personnaliser la barre d'outils.

Bijoy Thangaraj
la source
Existe-t-il un moyen de le rendre modifiable en cliquant avec le bouton droit et en sélectionnant "Personnaliser la barre d'outils"? (Similaire au Finder, Pages etc.)
sqwk
1
Avec la première solution, non. Mais, regardez l'approche alternative que j'ai ajoutée à ma réponse ci-dessus. De cette façon, vous avez la possibilité de personnaliser la barre d'outils.
Bijoy Thangaraj