wig*_*ing 16 macos swift swiftui
我正在使用 SwiftUI 开发一个新的 macOS 应用程序,但不知道如何定义窗口大小。在 AppDelegate 中,窗口大小定义如下:
// --- AppDelegate.swift ---
import Cocoa
import SwiftUI
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
var window: NSWindow!
func applicationDidFinishLaunching(_ aNotification: Notification) {
// Insert code here to initialize your application
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")
window.contentView = NSHostingView(rootView: ContentView())
window.makeKeyAndOrderFront(nil)
}
}
Run Code Online (Sandbox Code Playgroud)
ContentView 定义如下:
// --- ContentView.swift ---
import SwiftUI
struct ContentView : View {
var body: some View {
VStack {
Spacer()
Text("Top Text")
Spacer()
Text("Bottom Text")
Spacer()
}
}
}
Run Code Online (Sandbox Code Playgroud)
当我构建并运行应用程序时,会出现该窗口,但它的大小不正确。它大致显示为两个文本标签的大小,而不是 AppDelegate 中定义的 480x300 大小。
使用 SwiftUI 时,我应该如何定义 Mac 应用程序的窗口大小?
kon*_*iki 22
有时,这种行为可能会令人困惑。这是因为一旦您至少运行一次应用程序,如果您随后手动调整窗口大小并重新定位窗口,则委托中指定的大小将不再重要。
应用程序会记住用户何时调整了窗口大小,并将使用存储在 UserDefaults 中的信息,在键"NSWindow Frame Main Window" 下。如果要重置它,则需要使用defaults命令将其清除。
既然那不碍事,你的窗口如此狭窄的原因如下:
使用 SwiftUI,并非所有视图都是平等的。例如: Text() 是谦虚的。它只会根据需要占用尽可能多的空间。而其他视图,例如 Spacer(),会像它们的父母提供的一样扩展(我称之为贪婪)。
在您的情况下,您有一个 VStack,其中包含 Spacer()。这意味着 VStack 填充会扩展以填充其父级提供的高度。在这种情况下,来自委托的 300 pt(或存储在 UserDefaults 中的任何内容)。
另一方面,由于您在 HStack 中没有任何 Spacer(),因此 ContentView 只会水平扩展到它需要的位置。也就是说,与最宽的 Text() 视图一样宽。如果您HStack { Spacer() }在 VStack 内添加,您的内容视图将扩展以占据委托中指定的 480 pt(或存储在 UserDefaults 中的任何内容)。无需设置框架()。
另一种方法(为 ContentView 指定一个框架)基本上是告诉你的 ContentView 是 480x300,无论如何。事实上,如果你这样做,你将无法调整窗口大小!
所以现在你知道了,我认为很清楚……但是,这里有一些对你非常有用的东西:
还有另一个贪婪的视图可以帮助您调试窗口大小:GeometryReader。这种观点将始终采取尽可能多的提供。运行此示例,您将确切知道应用启动时提供了多少空间:
struct ContentView : View {
var body: some View {
GeometryReader { geometry in
VStack {
Text("\(geometry.size.width) x \(geometry.size.height)")
}.frame(width: geometry.size.width, height: geometry.size.height)
}
}
}
Run Code Online (Sandbox Code Playgroud)
我写了一篇关于GeometryReader的广泛文章,我建议你查看一下:https : //swiftui-lab.com/geometryreader-to-the-rescue/
顺便说一下,我的AppDelegate看起来像这样:
func applicationDidFinishLaunching(_ aNotification: Notification) {
// Insert code here to initialize your application
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")
window.contentView = NSHostingView(rootView: ContentView())
window.makeKeyAndOrderFront(nil)
}
Run Code Online (Sandbox Code Playgroud)
由于 Beta3,新项目的初始 ContentView,使用 maxWidth 和 maxHeight。一个聪明的选择。
struct ContentView : View {
var body: some View {
Text("Hello World")
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
Run Code Online (Sandbox Code Playgroud)
Moj*_*ini 16
只需给出一个大小content(或使其自定大小)并告诉窗口组将其大小限制为其内容:
@main
struct MySizingApp: App {
var body: some Scene {
WindowGroup {
ContentView()
.frame(minWidth: 350, minHeight: 350) // <- 1. Size here
}
.windowResizability(.contentSize) // <- 2. Add the restriction here
}
}
Run Code Online (Sandbox Code Playgroud)
我就是这样做的。它有一个启动大小和可调整大小。
struct windowSize {
// changes let to static - read comments
static minWidth : CGFloat = 100
static minHeight : CGFloat = 200
static maxWidth : CGFloat = 200
static maxHeight : CGFloat = 250
}
struct ContentView : View {
var body: some View {
Group() {
VStack {
Text("Hot Stuff")
.border(Color.red, width: 1)
Text("Hot Chocolate")
.border(Color.red, width: 1)
}
}
.frame(minWidth: windowSize().minWidth, minHeight: windowSize().minHeight)
.frame(maxWidth: windowSize().maxWidth, maxHeight: windowSize().maxHeight)
.border(Color.blue, width: 1)
}
}
Run Code Online (Sandbox Code Playgroud)
小智 8
斯威夫特用户界面
在我的例子中,您可以轻松地在主结构中使用(编译器指令),当我正在开发多平台应用程序(iPhone,iPad,mac)时,我用它来检测哪个屏幕应用程序正在运行
import SwiftUI
@main
struct DDStoreApp: App {
var body: some Scene {
WindowGroup {
// use compiler directives #if to detect mac version or ios version
#if os(macOS)
// use min wi & he to make the start screen 800 & 1000 and make max wi & he to infinity to make screen expandable when user stretch the screen
ContentView().frame(minWidth: 800, maxWidth: .infinity, minHeight: 1000, maxHeight: .infinity, alignment: .center)
#else
ContentView()
#endif
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
14002 次 |
| 最近记录: |