Como adiciono uma barra de ferramentas a um aplicativo macOS usando o SwiftUI?

9

Estou tentando adicionar uma barra de ferramentas dentro da barra de título a um aplicativo macOS usando o SwiftUI, algo semelhante ao mostrado abaixo.

Barra de ferramentas na barra de título no aplicativo macOS

Não consigo descobrir uma maneira de conseguir isso usando o SwiftUI. Atualmente, tenho minha barra de ferramentas (que possui apenas um campo de texto) dentro da minha visualização, mas quero movê-la para a barra de título.

Meu código atual:

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

Portanto, no meu caso, preciso ter o campo de texto dentro da barra de ferramentas.

Bijoy Thangaraj
fonte
Eu estou falando sobre SwiftUI no alvo macOS.
Bijoy Thangaraj
Não, o modificador navigationBarTitle não está disponível no macOS SwiftUI.
Bijoy Thangaraj
A barra de ferramentas não é suportada no SwiftUI por enquanto. Se você realmente precisa de um (por quê?), Use um do AppKit, ele ainda está lá ... realmente.
Asperi 29/02
@ Asperi Consegui fazer isso - veja a resposta abaixo. As barras de ferramentas (ou acessórios da barra de título) ainda são amplamente usadas nos aplicativos macOS, não é?
Bijoy Thangaraj
@Asperi Para usar o AppKit, você quis dizer usar o NSViewRepresentable for NSToolbar? Nesse caso, tentei esse método, mas não obtive sucesso. Se você tem uma solução dessa maneira, eu adoraria dar uma olhada.
Bijoy Thangaraj

Respostas:

4

Abordagem 1:

Isso é feito adicionando um acessório da barra de título. Consegui fazer isso modificando o arquivo AppDelegate.swift. Eu tive que aplicar algum preenchimento estranho para fazer com que parecesse certo.

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

    }
}

Resultado:

Conteúdo na barra de ferramentas do macOS

Abordagem 2 (método alternativo):

A idéia aqui é fazer a parte da barra de ferramentas usando o storyboard e o restante do aplicativo usando o SwiftUI. Isso é feito criando um novo aplicativo com o storyboard como interface do usuário. Em seguida, vá para o storyboard, exclua o View Controller padrão e adicione um novo NSHostingController. Conecte o Hosting Controller recém-adicionado à janela principal, definindo seu relacionamento. Adicione sua barra de ferramentas à janela usando o construtor de interfaces.

Configuração do Storyboard

Anexe uma classe personalizada à sua NSHostingControllere carregue sua visualização SwiftUI nela.

Exemplo de código abaixo:

import Cocoa
import SwiftUI

class HostingController: NSHostingController<SwiftUIView> {

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

    }

}

O uso dessa abordagem também permite personalizar a barra de ferramentas.

Bijoy Thangaraj
fonte
Existe uma maneira de torná-lo editável clicando com o botão direito e selecionando "Personalizar barra de ferramentas"? (Similar ao Finder, Pages etc.)
sqwk em
11
Com a primeira solução, não. Mas observe a abordagem alternativa que adicionei à minha resposta acima. Dessa forma, você tem a opção de personalizar a barra de ferramentas.
Bijoy Thangaraj