如何将 SwiftUI 按钮放入 NSToolbar?
How to put SwiftUI button into NSToolbar?
这是使用辅助视图控制器将 SwiftUI 插入 NSToolbar
的方式:
import SwiftUI
import PlaygroundSupport
var hostingView = NSHostingView(rootView:
ZStack {
Color.clear
HStack {
Text("Hey")
Text("SwiftUI")
}
}
.padding()
.edgesIgnoringSafeArea(.all)
)
hostingView.frame.size = hostingView.fittingSize
let titlebarAccessory = NSTitlebarAccessoryViewController()
titlebarAccessory.view = hostingView
titlebarAccessory.layoutAttribute = .trailing
let mask: NSWindow.StyleMask = [.titled, .closable, .miniaturizable, .resizable]
let window = NSWindow(
contentRect: .init(x: 0, y: 0, width: 480, height: 300),
styleMask: mask, backing: .buffered, defer: false)
window.center()
window.contentView = NSHostingView(rootView: Color(.windowBackgroundColor))
window.toolbar = .init()
window.titleVisibility = .hidden
window.addTitlebarAccessoryViewController(titlebarAccessory)
PlaygroundPage.current.liveView = window.contentView?.superview
上面的代码确实有效:
但是如果我们插入一个按钮:
HStack {
Text("Hey")
Button(action: {}) {
Text("SwiftUI")
}
}
它不会按预期工作:
有什么建议吗?
P。 S. 这是一个可行的解决方案:
HStack {
Text("Hey")
.offset(x: 0, y: -1)
Button(action: {}) {
Text("SwiftUI")
.offset(x: 0, y: -7)
}
}
.font(.caption)
将我的评论作为每个请求的答案发布。不一定是可靠的解决方案,但作为解决方法,您可以使用
Text("SwiftUI")
.padding(EdgeInsets(top: -7, leading: 0, bottom: 0, trailing: 0))
或 .offset
在按钮的文本上。无法保证该解决方案将持续多长时间。
工具栏项目更垂直 space。要修复该问题,请使用 Spacer 视图,它将按钮推到顶部:
VStack {
Button(action: {}) {
Text("Text")
}.frame(height: 22)
Spacer()
}
我最终处理它的方式(当用户使 window 全屏并且不管内容的高度*如何时它也能工作)如下所示。请注意,我在使用最新 Xcode 版本构建的 macOS 应用程序的 NSTitlebarAccessoryViewController 中的 NSHostingView 中使用工具栏视图(显然,在 macOS Catalina 上)。
重要的事情:*你仍然需要为框架设置一个固定的高度(但至少你不会依赖于 "variable" -7)并且仅将实际高度的一半偏移到顶部当有安全区域顶部插入时(在全屏模式下,显然不是),因此 GeometryReader 是必须的:
struct Toolbar : View {
var body: some View {
GeometryReader { geometry in
VStack {
Text("1st row")
Text("2nd row")
}
.offset(y: geometry.safeAreaInsets.top > 0 ? -geometry.size.height / 2 : 0)
}
.frame(height: 42)
}
}
以及创建 window 的位置:
let toolbar = NSHostingView(rootView: Toolbar())
toolbar.frame.size = toolbar.fittingSize
let toolbarController = NSTitlebarAccessoryViewController()
toolbarController.view = toolbar
window.addTitlebarAccessoryViewController(toolbarController)
似乎对按钮应用 PlainButtonStyle
有帮助。
默认样式正在做一些奇怪的魔术,破坏了 NSToolbar 中的布局。
这是使用辅助视图控制器将 SwiftUI 插入 NSToolbar
的方式:
import SwiftUI
import PlaygroundSupport
var hostingView = NSHostingView(rootView:
ZStack {
Color.clear
HStack {
Text("Hey")
Text("SwiftUI")
}
}
.padding()
.edgesIgnoringSafeArea(.all)
)
hostingView.frame.size = hostingView.fittingSize
let titlebarAccessory = NSTitlebarAccessoryViewController()
titlebarAccessory.view = hostingView
titlebarAccessory.layoutAttribute = .trailing
let mask: NSWindow.StyleMask = [.titled, .closable, .miniaturizable, .resizable]
let window = NSWindow(
contentRect: .init(x: 0, y: 0, width: 480, height: 300),
styleMask: mask, backing: .buffered, defer: false)
window.center()
window.contentView = NSHostingView(rootView: Color(.windowBackgroundColor))
window.toolbar = .init()
window.titleVisibility = .hidden
window.addTitlebarAccessoryViewController(titlebarAccessory)
PlaygroundPage.current.liveView = window.contentView?.superview
上面的代码确实有效:
但是如果我们插入一个按钮:
HStack {
Text("Hey")
Button(action: {}) {
Text("SwiftUI")
}
}
它不会按预期工作:
有什么建议吗?
P。 S. 这是一个可行的解决方案:
HStack {
Text("Hey")
.offset(x: 0, y: -1)
Button(action: {}) {
Text("SwiftUI")
.offset(x: 0, y: -7)
}
}
.font(.caption)
将我的评论作为每个请求的答案发布。不一定是可靠的解决方案,但作为解决方法,您可以使用
Text("SwiftUI")
.padding(EdgeInsets(top: -7, leading: 0, bottom: 0, trailing: 0))
或 .offset
在按钮的文本上。无法保证该解决方案将持续多长时间。
工具栏项目更垂直 space。要修复该问题,请使用 Spacer 视图,它将按钮推到顶部:
VStack {
Button(action: {}) {
Text("Text")
}.frame(height: 22)
Spacer()
}
我最终处理它的方式(当用户使 window 全屏并且不管内容的高度*如何时它也能工作)如下所示。请注意,我在使用最新 Xcode 版本构建的 macOS 应用程序的 NSTitlebarAccessoryViewController 中的 NSHostingView 中使用工具栏视图(显然,在 macOS Catalina 上)。
重要的事情:*你仍然需要为框架设置一个固定的高度(但至少你不会依赖于 "variable" -7)并且仅将实际高度的一半偏移到顶部当有安全区域顶部插入时(在全屏模式下,显然不是),因此 GeometryReader 是必须的:
struct Toolbar : View {
var body: some View {
GeometryReader { geometry in
VStack {
Text("1st row")
Text("2nd row")
}
.offset(y: geometry.safeAreaInsets.top > 0 ? -geometry.size.height / 2 : 0)
}
.frame(height: 42)
}
}
以及创建 window 的位置:
let toolbar = NSHostingView(rootView: Toolbar())
toolbar.frame.size = toolbar.fittingSize
let toolbarController = NSTitlebarAccessoryViewController()
toolbarController.view = toolbar
window.addTitlebarAccessoryViewController(toolbarController)
似乎对按钮应用 PlainButtonStyle
有帮助。
默认样式正在做一些奇怪的魔术,破坏了 NSToolbar 中的布局。