即使是在最小的应用程序中,也是最小的:
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
}
如果我在System Preferences
中更改屏幕的分辨率(例如从1920 x 1080到1600 x 900,或者返回),当我将鼠标悬停在SKView
上时,会出现旋转的沙滩球可以更长时间与窗口交互(例如,调整窗口大小)。令人沮丧的是,我在控制台(系统或Xcode)中什么也得不到,也不是每次都会发生这种情况。视图是来自xib
还是以编程方式创建,没有区别。
任何线索都会非常受欢迎。
如果有人能证实他们也看到了这一点,我也将非常感激。
(在OS X 10.10.3上的调试Xcode 6.3.2中构建,包括调试和发布)
答案 0 :(得分:0)
由于这是用这样一个最小的应用程序复制的,并且由于没有人响应,我被迫继续假设这是一个SpriteKit
错误。如果人们确认他们也看到了这一点,我会提交错误报告。在此期间,我现在无法提交我的应用程序,因为我知道只要用户更改显示配置,它就会崩溃。然而,为了避免崩溃,证明是相当棘手的......
首先,应用程序在调用NSApplication
的{{1}}之前崩溃。为了尽快发现事件,我们可以使用applicationDidChangeScreenParameters(:)
。这是一个C函数,其第一个参数(CGDisplayRegisterReconfigurationCallback
)目前无法在Swift中构造。要使用它,我必须下降到C和Objective-C:
<强> DisplayConfigurationChanges.h 强>
CFunctionPointer
<强> DisplayConfigurationChanges.m 强>
#import <Foundation/Foundation.h>
extern NSString * DisplayConfigurationWillChange;
extern NSString * DisplayConfigurationDidChange;
extern void StartNotificationsOnDisplayConfigurationChange();
extern void StopNotificationsOnDisplayConfigurationChange();
不要忘记在#import "DisplayConfigurationChanges.h"
NSString * DisplayConfigurationWillChange = @"DisplayConfigurationWillChange";
NSString * DisplayConfigurationDidChange = @"DisplayConfigurationidChange";
void DisplayReconfigurationBlock (CGDirectDisplayID display, CGDisplayChangeSummaryFlags flags, void *userInfo) {
if (flags & kCGDisplayBeginConfigurationFlag) {
[[NSNotificationCenter defaultCenter] postNotificationName:DisplayConfigurationWillChange object:nil];
} else {
[[NSNotificationCenter defaultCenter] postNotificationName:DisplayConfigurationDidChange object:nil];
}
}
void StartNotificationsOnDisplayConfigurationChange() {
CGDisplayRegisterReconfigurationCallback(DisplayReconfigurationBlock, NULL);
}
void StopNotificationsOnDisplayConfigurationChange() {
CGDisplayRemoveReconfigurationCallback(DisplayReconfigurationBlock, NULL);
}
-Bridging-Header.h
现在我们可以随时开始发布#import "DisplayConfigurationChanges.h"
和DisplayConfigurationWillChange
通知,并随时随地观察,包括应用的Swift端:
<强> AppDelegate.swift 强>
DisplayConfigurationDidChange
在应用程序运行时更改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)
}
}
中的显示分辨率(没有任何System Preferences
)将打印:
SKView
如果我们现在添加display will change (1920.0, 1080.0)
display did change (1600.0, 900.0)
,应用程序会崩溃,只打印上面的第一行。但这是成功的!这意味着我们确实得到了及时做出改变的通知。