【发布时间】:2021-09-29 16:55:11
【问题描述】:
我正在开发一个 mac 应用程序,我喜欢让初始窗口处于最大化状态,就像你按下带有加号的绿色按钮一样。 我不希望它是全屏的。
【问题讨论】:
标签: swift macos cocoa nswindow
我正在开发一个 mac 应用程序,我喜欢让初始窗口处于最大化状态,就像你按下带有加号的绿色按钮一样。 我不希望它是全屏的。
【问题讨论】:
标签: swift macos cocoa nswindow
处于缩放状态的应用与“最大化”不同。绿色加号图标表示缩放,表示“此内容的适当大小”。在某些应用程序中这是可见框架(正如 Eric D. 所讨论的),但它几乎可以是任何东西。例如,尝试缩放 Safari 窗口。
假设您真的想要“最大化”而不是“缩放”,那么 Eric 就在正确的轨道上,但可以做得更好。首先,如果有窗口的屏幕,您应该使用它。此外,您不应在启动期间为窗口调整大小设置动画(因为这在启动时可能看起来很尴尬)。
func applicationDidFinishLaunching(aNotification: NSNotification) {
if let screen = window.screen ?? NSScreen.mainScreen() {
window.setFrame(screen.visibleFrame, display: true)
}
}
您可能需要考虑使用NSWindowController 来管理它,而不是将其放在应用程序委托中。在这种情况下,您可以将其放入windowDidLoad。窗口控制器是 AppKit 中非常常见的工具(与视图控制器相反,视图控制器在历史上并不常见)。
如果您确实想要缩放行为,请熟悉NSWindowDelegate 方法windowWillUseStandardFrame(_:defaultFrame:)。您通常不应该在启动时直接调用zoom(_:),因为这会产生动画效果,但是您在委托中执行的任何逻辑都应该用于计算您的帧。同样,请确保将您的框架调整为显示在窗口屏幕上(如果有),而不是主屏幕。
理想情况下,您确实应该尊重用户使用的最后一帧,而不是将其强制显示为可见帧。如果您想进一步研究,这在 Cocoa 中称为frameAutosave。如果您只是在 Interface Builder 中设置自动保存名称,窗口控制器将帮助您自动管理它。 (虽然需要在第一次启动时计算帧以获得可见帧,所以它不会完全自动。)
在将默认框架设置为可见框架之前,请务必仔细考虑。这在大型显示器上可能非常巨大(那里仍然有很多 30 英寸的影院显示器,但即使在 27 英寸上也可能是相当压倒性的)。有时这很好,具体取决于您的应用,但我经常发现值得定义最大初始大小(同时允许用户将其放大)。
【讨论】:
您可以使用 NSScreen 的 visibleFrame 作为目标框架将窗口“缩放”到最大可用空间。假设window 是您的 NSWindow IBOutlet:
if let screen = NSScreen.mainScreen() {
window.setFrame(screen.visibleFrame, display: true, animate: true)
}
例如,在 AppDelegate.swift 中:
import Cocoa
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
@IBOutlet weak var window: NSWindow!
func applicationDidFinishLaunching(aNotification: NSNotification) {
if let screen = NSScreen.mainScreen() {
window.setFrame(screen.visibleFrame, display: true, animate: true)
}
}
【讨论】:
.mainScreen() 替换为 .main()。
window.screen
在 Swift 4.2 中:
class ViewController: NSViewController {
override func viewDidAppear() {
super.viewDidAppear()
view.window?.zoom(self) //bespread the screen
//view.window?.toggleFullScreen(self) //fullscreen
}
【讨论】:
2020 | SWIFT 5.1:
使用扩展:
extension NSWindowController {
func maximize() { self.window?.zoom(self) }
}
只需调用 NSWindowController 实例的maximize() :)
【讨论】:
斯威夫特 5
如果还有人遇到问题,请尝试在主线程中调用缩放功能。为我工作。
DispatchQueue.main.async {
self.view.window?.zoom(self)
}
【讨论】:
大家好,非常感谢您的帮助。
我正在开发基于文档的 mac 应用程序。我将您提供的代码放在 Document 类的 makeWindowControllers() 中,它就像一个魅力。
非常感谢。这是我使用的代码。
override func makeWindowControllers() {
// Returns the Storyboard that contains your Document window.
let storyboard = NSStoryboard(name: "Main", bundle: nil)
let windowController = storyboard.instantiateControllerWithIdentifier("Document Window Controller") as! NSWindowController
self.addWindowController(windowController)
if let screen = NSScreen.mainScreen() {
windowController.window?.setFrame(screen.visibleFrame, display: true, animate: true)
}
}
【讨论】:
此代码仅适用于单窗口应用程序,但很容易编辑以适用于多窗口应用程序
用于最大化和取消最大化窗口:
TheApp.maximized.toggle()
源代码
public class TheApp {
static var maximized: Bool {
get {
guard let visibleFrame = NSScreen.main?.visibleFrame,
let window = NSApp.mainWindow
else { return false }
return window.frame == visibleFrame
}
set { NSApp.mainWindow?.zoom(newValue) }
}
static var fullscreen: Bool {
get {
guard let screenFrame = NSScreen.main?.frame,
let window = NSApp.mainWindow
else { return false }
return window.frame == screenFrame
} set {
NSApp.mainWindow?.toggleFullScreen(newValue)
}
}
static var mimimized: Bool {
get { NSApp.mainWindow?.isMiniaturized ?? false }
set { NSApp?.mainWindow?.miniaturize(newValue) }
}
}
【讨论】: