如何在Swift

时间:2016-11-03 15:01:02

标签: swift struct notificationcenter

我尝试在Swift-3中创建一个对象,该对象将包含各种基本用户设置,可以在整个应用程序中轻松访问。我目前将此设置作为名为PTSettings的结构。它实现如下:

struct PTSettings {
    static var aUserSettings: String()
}

可以在应用程序周围轻松访问:PTSettings.aUserSetting = "Foo"

我在这里遇到的困难是我喜欢这个结构来观察来自NotificationCenter的UIScreen通知。当屏幕连接PTSettings初始化外部屏幕时,为其指定视图,显示横幅以让用户知道等...

我熟悉在UIViewController上完成所有这些任务;但是我不熟练使用结构。我希望当应用程序加载时,结构将被初始化,并且init将正在观察NotificationCenter,同时还检查在加载应用程序之前是否连接了屏幕。

以下是我目前的情况。

/// Struct containing various user-generate data such as color, messages and other settings.
struct PTSettings {


    // External UI
    //
    static var externalScreen: UIScreen!
    //
    static var externalWindow: UIWindow!
    //
    static var extDisplay: PTExternalDisplayVC?


    init () {
        // Receive notifications if a screen is connected or disconnected
        //
        let center = NotificationCenter.default
        center.addObserver(self, selector: #selector(PTSettings.handleScreenDidConnectNotification(notification:)), name: NSNotification.Name.UIScreenDidConnect, object: nil)
        center.addObserver(self, selector: #selector(PTSettings.handleScreenDidDisconnectNotification(notification:)), name: NSNotification.Name.UIScreenDidDisconnect, object: nil)
        center.addObserver(self, selector: #selector(PTSettings.handleScreenModeDidChangeNotification), name: NSNotification.Name.UIScreenModeDidChange, object: nil)
    }




    // MARK: External Displays
    //
    static func initializeExternalScreen(externalScreen:UIScreen) {
        self.externalScreen = externalScreen

        externalScreen.overscanCompensation = UIScreenOverscanCompensation(rawValue: 3)!

        // Create a new window sized to the external screen's bounds
        self.externalWindow = UIWindow(frame: self.externalScreen.bounds)

        // Assign screen object to screen property of the new window
        self.externalWindow.screen = externalScreen

        // Load the clock view
        let viewForExternalScreen = self.storyboard?.instantiateViewController(withIdentifier: "ExternalDisplay") as! PTExternalDisplayVC
        viewForExternalScreen.view.frame = self.externalWindow.frame

        // Add the view to the window
        self.externalWindow.addSubview(viewForExternalScreen.view)

        // Create a reference to the viewForExternalScreen
        self.extDisplay = viewForExternalScreen

        // Make the window visible
        self.externalWindow.makeKeyAndVisible()
    }
    //
    static func handleScreenDidConnectNotification (notification:Notification) {
        if let screen = notification.object as? UIScreen {
            initializeExternalScreen(externalScreen: screen)
        }
    }
    //
    static func handleScreenDidDisconnectNotification (notification:Notification) {
        if externalWindow != nil {
            externalWindow.isHidden = true
            externalWindow = nil
            displayConnectedLabel.text = "No Display"
            displayConnectedLabel.textColor = CustomColors.Red.color
            JSSAlertView().warning(self, title: "External Display Disconnected.")
        }
    }
    //
    static func handleScreenModeDidChangeNotification () {
        let screen = UIScreen.screens[1]
        initializeExternalScreen(externalScreen: screen)
    }

}

编译器抱怨init()方法中每次添加观察者都是这样的:

' #selector'的论点指静态方法' handleScreenDidConnectNotification(notification :)'没有暴露于Objective-C

然而,当在方法之前添加@objc时,它会抱怨:

@objc只能用于类的成员,@ objc协议和类的具体扩展。

我怎样才能达到预期的效果呢?我完全不采用这种方法吗?

1 个答案:

答案 0 :(得分:0)

  

我完全偏离这种方法

你确实完全离开了。将Objective-C(和Cocoa)与Swift区分开来。 Swift结构是纯粹的Swift功能。您正在尝试使用Cocoa功能,即通过选择器调用方法,使用Swift功能,结构。你不能这样做。 Swift结构缺少允许选择器工作的Objective-C内省功能。这就是为什么你只能为Objective-C类的方法创建一个选择器,即继承自NSObject (正如你过去所做的那样)。

但是,添加通知中心观察者another form,您使用尾随闭包/函数,而不是选择器。你可以试试(虽然我不保证任何东西)。