Wie füge ich einer macOS-App mit SwiftUI eine Symbolleiste hinzu?

9

Ich versuche, einer macOS-App mit SwiftUI eine Symbolleiste in der Titelleiste hinzuzufügen, ähnlich wie unten gezeigt.

Symbolleiste in der Titelleiste in der macOS App

Ich kann mit SwiftUI keinen Weg finden, dies zu erreichen. Derzeit habe ich meine Symbolleiste (die nur ein Textfeld enthält) in meiner Ansicht, möchte sie jedoch in die Titelleiste verschieben.

Mein aktueller Code:

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

In meinem Fall muss sich das Textfeld in der Symbolleiste befinden.

Bijoy Thangaraj
quelle
Ich spreche von SwiftUI in macOS target.
Bijoy Thangaraj
Nein, der Modifikator navigationBarTitle ist in macOS SwiftUI nicht verfügbar.
Bijoy Thangaraj
Die Symbolleiste wird in SwiftUI derzeit nicht unterstützt. Wenn Sie wirklich einen brauchen (warum?), Dann verwenden Sie einen von AppKit, er ist immer noch da ... wirklich.
Asperi
@Asperi Ich konnte dies tun - siehe die Antwort unten. Symbolleisten (oder Zubehör für die Titelleiste) werden in macOS-Apps immer noch häufig verwendet, nicht wahr?
Bijoy Thangaraj
@Asperi Um die von AppKit zu verwenden, meinten Sie die Verwendung von NSViewRepresentable für NSToolbar? Wenn ja, habe ich diese Methode ausprobiert, war aber nicht erfolgreich. Wenn Sie auf diese Weise eine Lösung haben, würde ich sie gerne ausprobieren.
Bijoy Thangaraj

Antworten:

4

Ansatz 1:

Dies erfolgt durch Hinzufügen eines Titelleistenzubehörs. Ich konnte dies erreichen, indem ich die Datei AppDelegate.swift änderte. Ich musste einige seltsame Polster auftragen, damit es richtig aussah.

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(""))

    }
}

Ergebnis:

Inhalt in der macOS-Symbolleiste

Ansatz 2 (alternative Methode):

Die Idee hier ist, den Symbolleisten-Teil mit Storyboard und den Rest der App mit SwiftUI zu erledigen. Dazu wird eine neue App mit Storyboard als Benutzeroberfläche erstellt. Gehen Sie dann zum Storyboard, löschen Sie den Standard-View-Controller und fügen Sie einen neuen hinzu NSHostingController. Verbinden Sie den neu hinzugefügten Hosting Controller mit dem Hauptfenster, indem Sie seine Beziehung festlegen. Fügen Sie Ihre Symbolleiste mit dem Interface Builder zum Fenster hinzu.

Storyboard-Konfiguration

Hängen Sie eine benutzerdefinierte Klasse an Ihre an NSHostingControllerund laden Sie Ihre SwiftUI-Ansicht hinein.

Beispielcode unten:

import Cocoa
import SwiftUI

class HostingController: NSHostingController<SwiftUIView> {

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

    }

}

Mit diesem Ansatz können Sie auch die Symbolleiste anpassen.

Bijoy Thangaraj
quelle
Gibt es eine Möglichkeit, es bearbeitbar zu machen, indem Sie mit der rechten Maustaste klicken und "Symbolleiste anpassen" auswählen? (Ähnlich wie im Finder, auf den Seiten usw.)
sqwk
1
Mit der ersten Lösung, nein. Schauen Sie sich jedoch den alternativen Ansatz an, den ich oben zu meiner Antwort hinzugefügt habe. Auf diese Weise erhalten Sie die Option, die Symbolleiste anzupassen.
Bijoy Thangaraj