更新 NSWindow 内容大小以适合 SwiftUI 视图

问题描述 投票:0回答:2

我有一个 SwiftUI 视图,由于可变长度字符串(例如由于本地化),它不知道大小。我需要调整包含的

NSWindow
的大小来修复内容。我可以提供固定/最小宽度。

使用 AppKit 委托创建新的 Mac 应用程序会产生一个相当简单的 AppDelegate:

import Cocoa
import SwiftUI

@main
class AppDelegate: NSObject, NSApplicationDelegate {
    func applicationDidFinishLaunching(_ aNotification: Notification) {
        // Create the SwiftUI view that provides the window contents.
        let contentView = ContentView()

        // 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.isReleasedWhenClosed = false
        window.center()
        window.setFrameAutosaveName("Main Window")
        window.contentView = NSHostingView(rootView: contentView)
        window.makeKeyAndOrderFront(nil)
    }
}

然后我有一个带有按钮的 SwiftUI,该按钮添加到标签的文本中以模拟更改文本:

import SwiftUI

struct ContentView: View {
    @State var text = "Hello, World!"

    var body: some View {
        VStack {
            Text(text)
                .frame(maxWidth: .infinity, maxHeight: .infinity)
            Button("Add Some Text") {
                text += "\nHello, World!"
            }
        }
    }
}

单击按钮最终会导致添加过多行文本并且标签被截断。

当 SwiftUI 视图的大小发生变化时,如何更新容器

NSWindow
的内容大小?

macos swiftui nswindow
2个回答
14
投票

据我了解,您需要以下内容(使用 Xcode 12.1 进行测试)

struct ContentView: View {
    @State var text = "Hello, World!"

    var body: some View {
        VStack {
            Text(text)
                .frame(maxWidth: .infinity, maxHeight: .infinity)
            Button("Add Some Text") {
                text += "\nHello, World!"
            }
        }
        .frame(minWidth:480, minHeight: 300)     // << this for default
        .fixedSize()                             // << this to update container 
    }
}

0
投票

带有弹出窗口的 Safari 扩展“JS Blocker”的 100% 工作示例(AppKit XIB 表单 + SwiftUI 标记):

import SafariServices
import SwiftUI

struct Popup: View {

    static let FRAME_SIZE_W: CGFloat = 450
    static let FRAME_SIZE_H: CGFloat = 450

    var body: some View {
        VStack(spacing: 0) {
            Text("POPUP")
        }.frame(width: Popup.FRAME_SIZE_W, height: Popup.FRAME_SIZE_H)
    }
}


class PopupViewController: SFSafariExtensionViewController {

    static let shared: PopupViewController = {
        return PopupViewController()
    }()

    static var popupShared: Popup = {
        return Popup()
    }()

    var popupHost: NSHostingController<Popup>? = nil
    var popupView: NSView? = nil

    override func viewDidLoad() {
        super.viewDidLoad()
        self.popupHost = NSHostingController(rootView: PopupViewController.popupShared)
        self.popupView = self.popupHost!.view
        self.view.addSubview(self.popupView!)
    }

    override func viewDidAppear() {
        self.popupView!.frame     = CGRect(x: 0, y: 0, width: Int(self.popupView!.intrinsicContentSize.width), height: Int(self.popupView!.intrinsicContentSize.height))
        self.preferredContentSize = CGSize(            width: Int(self.popupView!.intrinsicContentSize.width), height: Int(self.popupView!.intrinsicContentSize.height))
    }

}
© www.soinside.com 2019 - 2024. All rights reserved.