【问题标题】:How to set the window size and position programmatically for a SpriteKit/GameScene app on OSX如何在 OSX 上以编程方式为 SpriteKit/GameScene 应用程序设置窗口大小和位置
【发布时间】:2019-04-10 10:08:50
【问题描述】:

我在 Xcode 中创建了一个作为 SpriteKit/GameScene 应用程序的基本项目。我想以编程方式设置窗口大小。我在这里阅读了很多答案,并在其他地方阅读了一些教程,但我阅读的内容都没有帮助。

This answer 谈到覆盖WindowController.windowDidLoad,但GameScene 没有给我WindowController。它确实给了我一个ViewController。 This tutorial 说你可以从ViewController.viewDidLoad() 调用self.view.window?.setFrame(),但我的窗口顽固地保持不变。我在 SO 上找到的一些答案都是关于自动布局的。我没有什么要摆的。这只是一个 SpriteKit 入门项目。

This answer 说你可以在ViewController.viewWillAppear() 中设置preferredContentSize,这实际上让我可以设置窗口大小,但是如果我把窗口设置得太大(因为我不得不猜测一个合法的大小),它不可拖动或调整大小。 This answer 说您可以从 view.bounds.size 获得正确的尺寸,但它说的是 800 x 600,这与我的屏幕尺寸相去甚远。 This answer 说你可以从 UIScreen.mainScreen().bounds.size 获得边界,但我的 GameScene/SpriteKit 入门项目中似乎没有任何类型的 UIScreen。

如何获取屏幕大小,如何以编程方式设置窗口大小和位置?

另外,我似乎再也找不到的其他答案之一说你应该删除GameScene.sks,我这样做了,除了大小之外,一切似乎都很好。

【问题讨论】:

  • "GameScene 没有给我一个 WindowController" Que!?基本视图控制器应该连接到它的窗口控制器。
  • 谢谢,但我不知道这些词是什么意思,也不知道如何使用它们。干杯
  • 如果你的项目没有给你一个窗口控制器,你可以自己通过Interface Builder添加一个。

标签: swift macos sprite-kit


【解决方案1】:

如果一些 UI 专家可以评论这是否是“正确”的答案,那就太棒了,但这是我根据“El Tomato”相当神秘的 cmets 所做的疯狂猜测。首先,将以下内容添加到 ViewController.swift:

class WildGuessWindowController: NSWindowController {
    override func windowDidLoad() {
        if let screenSize = window?.screen?.frame {
            window!.setFrame(screenSize, display: true)
            print(screenSize)
        }

        super.windowDidLoad()
    }
}

接下来,在项目导航器中打开 Main.storyboard。您可能会看到类似以下内容:

单击“窗口控制器”框,然后打开右侧面板。您应该会看到类似这样的内容。

请注意箭头旁边的框,其中有一个灰色的类名。 (还请注意,您可能必须单击“身份检查器”按钮,上面的蓝色按钮显示“自定义类”。)现在单击该下拉菜单,您应该会看到WildGuessWindowController。选择它,你就设置好了。构建并运行。该框架将实例化您的类,并运行windowDidLoad()。

【讨论】:

    【解决方案2】:

    为 Swift 5 更新

    窗口大小

    如果你想在那里实现NSWindowDelegate,记得将NSWindowDelegate添加到你的NSViewController类中(即viewDidLoad()、viewWillAppear()、viewDidAppear()等)

    NSView

    class ViewController: NSViewController, NSWindowDelegate {
    
        override func viewWillAppear() {
            fillWindow()
        }
        
        /// Sizes window to fill max screen size
        func fillWindow() {
            if let screenSize = view.window?.screen?.frame {
                view.window!.setFrame(screenSize, display: true)
            }
        }
    
    }
    

    NSWindow

    class WindowController: NSWindowController {
    
        override func windowDidLoad() {
            super.windowDidLoad()
        
            fillWindow()
        }
    
        /// Sizes window to fill max screen size
        func fillWindow() {
            if let screenSize = window?.screen?.frame {
                window!.setFrame(screenSize, display: true)
            }
        }
    
    }
    

    打印到调试器控制台

    print(screenSize)    // embed within if let screenSize { ... }
    

    窗口位置

    查看完整答案以及已实现的代码here。

    extension NSWindow {
        
        /// Positions the `NSWindow` at the horizontal-vertical center of the `visibleFrame` (takes Status Bar and Dock sizes into account)
        public func positionCenter() {
            if let screenSize = screen?.visibleFrame.size {
                self.setFrameOrigin(NSPoint(x: (screenSize.width-frame.size.width)/2, y: (screenSize.height-frame.size.height)/2))
            }
        }
        /// Centers the window within the `visibleFrame`, and sizes it with the width-by-height dimensions provided.
        public func setCenterFrame(width: Int, height: Int) {
            if let screenSize = screen?.visibleFrame.size {
                let x = (screenSize.width-frame.size.width)/2
                let y = (screenSize.height-frame.size.height)/2
                self.setFrame(NSRect(x: x, y: y, width: CGFloat(width), height: CGFloat(height)), display: true)
            }
        }
        /// Returns the center x-point of the `screen.visibleFrame` (the frame between the Status Bar and Dock).
        /// Falls back on `screen.frame` when `.visibleFrame` is unavailable (includes Status Bar and Dock).
        public func xCenter() -> CGFloat {
            if let screenSize = screen?.visibleFrame.size { return (screenSize.width-frame.size.width)/2 }
            if let screenSize = screen?.frame.size { return (screenSize.width-frame.size.width)/2 }
            return CGFloat(0)
        }
        /// Returns the center y-point of the `screen.visibleFrame` (the frame between the Status Bar and Dock).
        /// Falls back on `screen.frame` when `.visibleFrame` is unavailable (includes Status Bar and Dock).
        public func yCenter() -> CGFloat {
            if let screenSize = screen?.visibleFrame.size { return (screenSize.height-frame.size.height)/2 }
            if let screenSize = screen?.frame.size { return (screenSize.height-frame.size.height)/2 }
            return CGFloat(0)
        }
    
    }
    

    用法

    NSWindow

    将现有窗口定位到 visibleFrame 的中心。

    window!.positionCenter()
    

    在 visibleFrame 的中心设置一个新的窗口框架,带有尺寸

    window!.setCenterFrame(width: 900, height: 600)
    

    NSView

    使用xCenter() 和yCenter() 得到visibleFrame 的中心x-y 点。

    let x = self.view.window?.xCenter() ?? CGFloat(0)
    let y = self.view.window?.yCenter() ?? CGFloat(0)
    self.view.window?.setFrame(NSRect(x: x, y: y, width: CGFloat(900), height: CGFloat(600)), display: true)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-29
      相关资源
      最近更新 更多