मैं SwiftUI का उपयोग करके macOS ऐप में टूलबार कैसे जोड़ूं?


11

मैं शीर्षक पट्टी के अंदर एक टूलबार जोड़ने की कोशिश कर रहा हूं जो कि स्विफ्टयूआई का उपयोग करते हुए एक मैकओएस ऐप में है, जो नीचे दिखाया गया है।

MacOS ऐप में टाइटलबार में टूलबार

मैं SwiftUI का उपयोग करके इसे प्राप्त करने के तरीके का पता लगाने में असमर्थ हूं। वर्तमान में, मेरे पास मेरा टूलबार है (जो कि एक टेक्स्ट फ़ील्ड है) मेरे विचार के अंदर है, लेकिन मैं इसे शीर्षक बार में स्थानांतरित करना चाहता हूं।

मेरा वर्तमान कोड:

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

तो, मेरे मामले में, मुझे टूलबार के अंदर टेक्स्टफील्ड की आवश्यकता है।


मैं macOS के लक्ष्य में मुक्केबाज़ी SwiftUI की बात कर रहा हूँ।
बिजोय थंगराज

नहीं, नैविगेशनबैरिटल संशोधक macOS SwiftUI में उपलब्ध नहीं है।
बिजय थंगराज

अभी के लिए SwiftUI में टूलबार समर्थित नहीं है। यदि आपको वास्तव में एक (क्यों?) की आवश्यकता है, तो AppKit से एक का उपयोग करें, यह अभी भी है ... वास्तव में।
असेरी

@Asperi मैं ऐसा करने में सक्षम था - कृपया नीचे उत्तर देखें। टूलबार (या टाइटलबार एक्सेसरीज़) अभी भी व्यापक रूप से macOS ऐप में उपयोग किए जाते हैं, है ना?
बिजॉय थंगराज

@Asperi AppKit से एक का उपयोग करने के लिए, क्या आपका मतलब NSSTRbar के लिए NSViewRepresentable का उपयोग करना है? यदि हां, तो मैंने वह तरीका आजमाया लेकिन वह सफल नहीं था। यदि आपके पास इस तरह से एक समाधान है, तो मैं इसे जांचना पसंद करूंगा।
बिजॉय थंगराज

जवाबों:


6

दृष्टिकोण 1:

यह एक शीर्षक पट्टी गौण को जोड़कर किया जाता है। मैं AppDelegate.swift फ़ाइल को संशोधित करके इसे प्राप्त करने में सक्षम था। मुझे इसे सही दिखने के लिए कुछ अजीब तरह की पैडिंग लगानी पड़ी।

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

    }
}

परिणाम:

MacOS टूलबार के अंदर की सामग्री

दृष्टिकोण 2 (वैकल्पिक विधि):

यहाँ विचार स्टोरीबोर्ड और शेष ऐप का उपयोग करके टूलबार भाग को स्विफ्टयूआई का उपयोग करना है। यह यूजर इंटरफेस के रूप में स्टोरीबोर्ड के साथ एक नया ऐप बनाकर किया जाता है। फिर स्टोरीबोर्ड पर जाएं और डिफ़ॉल्ट व्यू कंट्रोलर को हटाकर एक नया जोड़ें NSHostingController। अपने रिश्ते को सेट करके नए जोड़े गए होस्टिंग कंट्रोलर को मुख्य विंडो से कनेक्ट करें। इंटरफ़ेस बिल्डर का उपयोग करके अपने टूलबार को विंडो में जोड़ें।

स्टोरीबोर्ड विन्यास

अपने लिए एक कस्टम क्लास अटैच करें NSHostingControllerऔर उसमें अपना SwiftUI व्यू लोड करें।

नीचे दिए गए उदाहरण कोड:

import Cocoa
import SwiftUI

class HostingController: NSHostingController<SwiftUIView> {

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

    }

}

इस दृष्टिकोण का उपयोग करना आपको टूलबार को अनुकूलित करने की क्षमता भी देता है।


क्या "कस्टमाइज़ टूलबार" पर राइट क्लिक और चयन करके इसे संपादन योग्य बनाने का कोई तरीका है? (फाइंडर, पेज आदि के समान)
sqwk

2
पहले उपाय के साथ, नहीं। लेकिन, ऊपर दिए गए मेरी प्रतिक्रिया में मैंने जो वैकल्पिक दृष्टिकोण जोड़ा है, उसे देखें। इस तरह, आपको टूलबार को अनुकूलित करने का विकल्प मिलता है।
बिजय थंगराज

@BijoyThangaraj टूलबार में बटन का उपयोग करने के Stateचर को कैसे बदलें SwiftUIView? मैंने कोशिश की लेकिन राज्य नहीं बदला।
एलन

@Alan, ऐसा करने का एक तरीका आपके WindowController से एक अधिसूचना पोस्ट करके होगा जिसे आप अपने HostingController में देख सकते हैं। अपने HostingController में, आप एक ObservableObject पकड़ सकते हैं और प्राप्त अधिसूचना के आधार पर इसके गुणों को संशोधित कर सकते हैं। अंत में, आप इस अवलोकन योग्य वस्तु को अपने स्विफ्टविवि को इस तरह से पास कर सकते हैं:super.init(coder: coder, rootView: AnyView(SwiftUIView().environmentObject(myObservableObject)))
बिजोय

0

UIKit + उत्प्रेरक

https://developer.apple.com/documentation/uikit/uititlebar

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {

        guard let windowScene = (scene as? UIWindowScene) else { return }
        let window = UIWindow(windowScene: windowScene)

        if let titlebar = windowScene.titlebar {

            //toolbar
            let identifier = NSToolbar.Identifier(toolbarIdentifier)
            let toolbar = NSToolbar(identifier: identifier)
            toolbar.allowsUserCustomization = true
            toolbar.centeredItemIdentifier = NSToolbarItem.Identifier(rawValue: centerToolbarIdentifier)
            titlebar.toolbar = toolbar
            titlebar.toolbar?.delegate = self

            titlebar.titleVisibility = .hidden
            titlebar.autoHidesToolbarInFullScreen = true
        }

        window.makeKeyAndVisible()

    }
#if targetEnvironment(macCatalyst)
let toolbarIdentifier = "com.example.apple-samplecode.toolbar"
let centerToolbarIdentifier = "com.example.apple-samplecode.centerToolbar"
let addToolbarIdentifier = "com.example.apple-samplecode.add"

extension SceneDelegate: NSToolbarDelegate {

    func toolbar(_ toolbar: NSToolbar, itemForItemIdentifier itemIdentifier: NSToolbarItem.Identifier, willBeInsertedIntoToolbar flag: Bool) -> NSToolbarItem? {
        if itemIdentifier == NSToolbarItem.Identifier(rawValue: toolbarIdentifier) {
            let group = NSToolbarItemGroup(itemIdentifier: NSToolbarItem.Identifier(rawValue: toolbarIdentifier), titles: ["Solver", "Resistance", "Settings"], selectionMode: .selectOne, labels: ["section1", "section2", "section3"], target: self, action: #selector(toolbarGroupSelectionChanged))

            group.setSelected(true, at: 0)

            return group
        }

        if itemIdentifier == NSToolbarItem.Identifier(rawValue: centerToolbarIdentifier) {
            let group = NSToolbarItemGroup(itemIdentifier: NSToolbarItem.Identifier(rawValue: centerToolbarIdentifier), titles: ["Solver1", "Resistance1", "Settings1"], selectionMode: .selectOne, labels: ["section1", "section2", "section3"], target: self, action: #selector(toolbarGroupSelectionChanged))

            group.setSelected(true, at: 0)

            return group
        }

        if itemIdentifier == NSToolbarItem.Identifier(rawValue: addToolbarIdentifier) {
            let barButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.add, target: self, action: #selector(self.add(sender:)))
            let button = NSToolbarItem(itemIdentifier: itemIdentifier, barButtonItem: barButtonItem)
            return button
        }

        return nil
    }

    @objc func toolbarGroupSelectionChanged(sender: NSToolbarItemGroup) {
        print("selection changed to index: \(sender.selectedIndex)")
    }

    @objc func add(sender: UIBarButtonItem) {
        print("add clicked")
    }

    func toolbarDefaultItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
        [NSToolbarItem.Identifier(rawValue: toolbarIdentifier), NSToolbarItem.Identifier(rawValue: centerToolbarIdentifier), NSToolbarItem.Identifier.flexibleSpace,
            NSToolbarItem.Identifier(rawValue: addToolbarIdentifier),
            NSToolbarItem.Identifier(rawValue: addToolbarIdentifier)]
    }

    func toolbarAllowedItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
        self.toolbarDefaultItemIdentifiers(toolbar)
    }

}
#endif
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.