¿Cómo agrego una barra de herramientas a una aplicación macOS usando SwiftUI?

9

Estoy tratando de agregar una barra de herramientas dentro de la barra de título a una aplicación macOS usando SwiftUI, algo similar a lo que se muestra a continuación.

Barra de herramientas en la barra de título en la aplicación macOS

No puedo encontrar una manera de lograr esto usando SwiftUI. Actualmente, tengo mi barra de herramientas (que solo tiene un campo de texto) dentro de mi vista, pero quiero moverla a la barra de título.

Mi código actual:

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

Entonces, en mi caso, necesito tener el campo de texto dentro de la barra de herramientas.

Bijoy Thangaraj
fuente
Estoy hablando de SwiftUI en el objetivo de macOS.
Bijoy Thangaraj
No, el modificador navigationBarTitle no está disponible en macOS SwiftUI.
Bijoy Thangaraj
La barra de herramientas no es compatible con SwiftUI por ahora. Si realmente necesita uno (¿por qué?), Use uno de AppKit, todavía está allí ... realmente.
Asperi
@Asperi Pude hacer esto, vea la respuesta a continuación. Las barras de herramientas (o accesorios de la barra de título) todavía se usan ampliamente en las aplicaciones de macOS, ¿no es así?
Bijoy Thangaraj
@Asperi Para usar el de AppKit, ¿te refieres a usar NSViewRepresentable para NSToolbar? Si es así, probé ese método pero no tuve éxito. Si tiene una solución de esa manera, me encantaría echarle un vistazo.
Bijoy Thangaraj

Respuestas:

4

Enfoque 1:

Esto se hace agregando un accesorio de barra de título. Pude hacer esto modificando el archivo AppDelegate.swift. Tuve que aplicar un relleno extraño para que se vea 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(""))

    }
}

Resultado:

Contenido dentro de la barra de herramientas de macOS

Enfoque 2 (Método alternativo):

La idea aquí es hacer la parte de la barra de herramientas usando storyboard y el resto de la aplicación usando SwiftUI. Esto se hace creando una nueva aplicación con storyboard como interfaz de usuario. Luego vaya al guión gráfico y elimine el controlador de vista predeterminado y agregue uno nuevo NSHostingController. Conecte el controlador de alojamiento recientemente agregado a la ventana principal configurando su relación. Agregue su barra de herramientas a la ventana usando el generador de interfaces.

Configuración del guión gráfico

Adjunte una clase personalizada a su NSHostingControllery cargue su vista SwiftUI en ella.

Código de ejemplo a continuación:

import Cocoa
import SwiftUI

class HostingController: NSHostingController<SwiftUIView> {

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

    }

}

El uso de este enfoque también le brinda la posibilidad de personalizar la barra de herramientas.

Bijoy Thangaraj
fuente
¿Hay alguna manera de hacerlo editable haciendo clic derecho y seleccionando "Personalizar barra de herramientas"? (Similar al Finder, páginas, etc.)
sqwk
1
Con la primera solución, no. Pero, mire el enfoque alternativo que agregué a mi respuesta anterior. De esa manera, obtienes la opción de personalizar la barra de herramientas.
Bijoy Thangaraj