Macos SKView在更改屏幕参数时压碎应用程序
即使是在最小的应用程序中,也非常小:Macos SKView在更改屏幕参数时压碎应用程序,macos,sprite-kit,Macos,Sprite Kit,即使是在最小的应用程序中,也非常小: import Cocoa import SpriteKit @NSApplicationMain class AppDelegate: NSObject, NSApplicationDelegate { @IBOutlet weak var window: NSWindow! @IBOutlet weak var skView: SKView! // in MainMeny.xib of the template SpriteKit ap
import Cocoa
import SpriteKit
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
@IBOutlet weak var window: NSWindow!
@IBOutlet weak var skView: SKView! // in MainMeny.xib of the template SpriteKit app
}
如果我在系统首选项中更改屏幕分辨率(例如从1920 x 1080更改为1600 x 900,或从后面更改),则当我将鼠标悬停在SKView
上时,会出现旋转的海滩球,并且无法再与窗口交互(例如调整窗口大小)。令人沮丧的是,我在控制台(无论是系统还是Xcode)中什么也没有得到,也不是每次都会发生,尽管大多数情况下都会发生。视图是否来自xib
或是否以编程方式创建都没有区别
任何线索都欢迎
如果有人能证实他们也看到了这一点,我也将非常感激
(在OS X 10.10.3上的debug Xcode 6.3.2中构建,包括调试和发布)由于这是用这样一个最小的应用程序复制的,而且没有人响应,因此我不得不继续假设这是一个SpriteKit
错误。如果人们确认他们也看到了这一点,我会提交一份bug报告。同时,我无法提交我的应用程序,因为我知道只要用户更改显示配置,它就会崩溃。然而,要避免撞车却相当棘手
首先,应用程序在调用NSApplication
的applicationIDChangeScreenParameters(:)
之前崩溃。为了更快地捕获事件,我们可以使用CGDisplayRegisterReconfigurationCallback
。这是一个C函数,其第一个参数(aCFunctionPointer
)目前无法在Swift中构造。要使用它,我必须下降到C和Objective-C:
显示配置更改。h
#import <Foundation/Foundation.h>
extern NSString * DisplayConfigurationWillChange;
extern NSString * DisplayConfigurationDidChange;
extern void StartNotificationsOnDisplayConfigurationChange();
extern void StopNotificationsOnDisplayConfigurationChange();
不要忘记将其导入-bridgeing Header.h
#import "DisplayConfigurationChanges.h"
现在,我们可以随时发布DisplayConfigurationWillChange
和DisplayConfigurationDidChange
通知,并在任何地方观察它们,包括应用程序的Swift端:
AppDelegate.swift
import Cocoa
import SpriteKit
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
@IBOutlet weak var window: NSWindow!
func displayWillChange() {
println("display will change \(NSScreen.mainScreen()!.frame.size)")
}
func applicationDidChangeScreenParameters(notification: NSNotification) {
println("display did change \(NSScreen.mainScreen()!.frame.size)")
}
func applicationDidFinishLaunching(aNotification: NSNotification) {
StartNotificationsOnDisplayConfigurationChange()
NSNotificationCenter.defaultCenter().addObserver(self, selector: "displayWillChange", name: DisplayConfigurationWillChange, object: nil)
}
func applicationWillTerminate(notification: NSNotification) {
StopNotificationsOnDisplayConfigurationChange()
NSNotificationCenter.defaultCenter().removeObserver(self)
}
}
在应用程序运行时(无任何SKView
s),更改系统首选项中的显示分辨率将打印:
display will change (1920.0, 1080.0)
display did change (1600.0, 900.0)
如果我们现在添加一个SKView
,应用程序将崩溃,只打印上面的第一行。但这就是成功!这意味着我们确实及时收到了更改通知,可以采取一些措施。事实证明,我们唯一能做的“改变”就是重新启动应用程序!(如果您想知道如何做到这一点,请参阅。)谢天谢地,在我们的例子中,这对用户来说没有什么影响,但仍然远远不够理想。
display will change (1920.0, 1080.0)
display did change (1600.0, 900.0)