swift - NSTextView/NSViewController\NSNotification 用于 SWIFT 中 MacOS 应用程序的控制台日志功能

标签 swift macos nstextview nsviewcontroller nsnotification

我正在尝试开发一个应用程序,其中包含一个 Storyboard和一个我想用来记录应用程序事件和用户反馈的 NSTextView。我从主视图的复选框开关加载 View (控制台日志 View 在应用程序启动时默认打开)。到目前为止,应用程序启动时一切正常,第二个 View 按照 viewDidLoad() 函数的预期处理文本。

控制台日志 View 的 NSViewController 类是:

class ConsoleLogViewController: NSViewController,NSTextViewDelegate {

@IBOutlet var textViewConsoleLog: NSTextView!

override func viewWillDisappear() {
    (representedObject as! NSButton).isEnabled = true
    (representedObject as! NSButton).state = NSOffState
}

override func viewDidLoad() {
    super.viewDidLoad()
    // Do view setup here.

    textViewConsoleLog.delegate = self
    textViewConsoleLog.string = "All new journal events are logged to this window"
    textViewConsoleLog.string?.append("\n")
    textViewConsoleLog.string?.append("*********************************************")
    textViewConsoleLog.string?.append("\n")
    textViewConsoleLog.string?.append("\n")
} // END OF viewDidLoad()


func addLogToConsoleWindow(newLogEntry: String) {
    textViewConsoleLog.string? = (newLogEntry)
    textViewConsoleLog.string?.append("\n")
} // END OF addLogToConsoleWindow()

}//ConsoleLogViewController 结束

View 是使用以下函数调用从主视图 Controller (下图中名为“Control”)启动的:

    func showConsoleLogView() {
    let buttonCall = chkBoxConsoleLog
    performSegue(withIdentifier: "sequeConsoleView", sender: buttonCall)
}  //  END OF showConsoleLogView()

在主视图 Controller 中,我创建了一个 ConsoleLogViewController 实例,然后尝试使用函数 addLogToConsoleWindow 将附加日志信息附加到 textViewConsoleLog。主视图 Controller 中的相关代码片段是:

    let consoleOutputPrintStatement = ConsoleLogViewController()  // Create an instance of ConsoleLogViewController to allow logging to the new console window

consoleOutputPrintStatement.addLogToConsoleWindow(newLogEntry: "Loading journal files")

但是,当我运行该应用程序并尝试编写额外的文本行时,我收到了一个 fatal error :在展开可选值时意外发现 nil。很明显,textViewConsoleLog 对象为 nil 并且正在创建错误。

我假设问题是我正在创建该类的另一个实例,因此我试图将额外的文本附加到尚未启动的 textViewConsoleLog 对象(或类似的东西!)。

应用首次运行时如下所示:

enter image description here

那么 - 我是不是走错了路,试图使用 NSTextView 开发一个控制台的日志记录功能?或者我关闭但需要使用 NSTextView 的不同方法才能使其工作?如何使用从其他 viewController 生成的相关字符串更新 NSTextField 中的文本?

非常感谢任何帮助或指导。

最佳答案

好的 - 我终于找到了一个使用 NSNotification 的解决方案 - 事后看来这很明显。

控制台日志 View 中的相关代码如下所示,类被设置为使用 addObserver 方法接收来自 NotificationCenter 的通知。

class ConsoleLogViewController: NSViewController,NSTextViewDelegate {

@IBOutlet var textViewConsoleLog: NSTextView!

let controlCentreDidSendConsoleNotification = "TCCEDJ.controlCentreDidSendConsoleNotification"
let controlCentreDidSendConsoleNotificationMessageKey = "TCCEDJ.controlCentreDidSendConsoleNotificationMessageKey"


override func viewWillDisappear() {
    (representedObject as! NSButton).isEnabled = true
    (representedObject as! NSButton).state = NSOffState
}


override func viewDidLoad() {
    super.viewDidLoad()

    textViewConsoleLog.delegate = self
    textViewConsoleLog.string = "All new journal events are logged to this window"
    textViewConsoleLog.string?.append("\n")
    textViewConsoleLog.string?.append("*********************************************")
    textViewConsoleLog.string?.append("\n")
    textViewConsoleLog.string?.append("\n")

    //  set up notification centre
    let notificationCentre = NotificationCenter.default
    notificationCentre.addObserver(self, selector: #selector(addLogToConsoleWindow), name: NSNotification.Name(rawValue: controlCentreDidSendConsoleNotification), object: nil)
} // END OF viewDidLoad()


@objc func addLogToConsoleWindow(newLogEntry: NSNotification) {

    let userInfo = newLogEntry.userInfo as! [String: String]
    let newLogEntryString = userInfo[controlCentreDidSendConsoleNotificationMessageKey]!

    textViewConsoleLog.string?.append(newLogEntryString)
    textViewConsoleLog.string?.append("\n")
    textViewConsoleLog.scrollRangeToVisible(NSMakeRange((textViewConsoleLog.string?.characters.count)! - 1, 0))
} // END OF addLogToConsoleWindow()

}//ConsoleLogViewController 结束

主视图 Controller 中的相关代码是:

    // Set up variables to use with notification centre
let controlCentreDidSendConsoleNotification = "TCCEDJ.controlCentreDidSendConsoleNotification"
let controlCentreDidSendConsoleNotificationMessageKey = "TCCEDJ.controlCentreDidSendConsoleNotificationMessageKey"

    let testLog = [controlCentreDidSendConsoleNotificationMessageKey: "Test log on button push"]
    let notificationCentre = NotificationCenter.default
    notificationCentre.post(name: NSNotification.Name(rawValue: controlCentreDidSendConsoleNotification), object: self, userInfo: testLog)

现在一切都符合我正在寻找的行为。

关于swift - NSTextView/NSViewController\NSNotification 用于 SWIFT 中 MacOS 应用程序的控制台日志功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44214623/

相关文章:

cocoa - NSTextView 中插入符号下方的 NSPopover

ios - 为什么 viewDidLayoutSubviews 和 viewWillLayoutSubviews 被调用了两次?

swift - 无法使用 '_' 类型的参数列表调用 '_' - 我应该使用这两个选项中的哪一个?

arrays - 为什么我必须创建一个函数来将项目添加到 Swift 中的数组?

macos - 使用绑定(bind)时将 NSPopUpButton 内容与标签分开

swift - 如何使用 Swift3 在​​正确的位置填充日历模板的日期?

macos - 如何设置 NSTextView 中所有文本的颜色(而不仅仅是随后输入的文本)

ios - Objective C 的 Swift 语法

Ruby:安装一个 yanked gem(例如 OS X 10.9 上的 wkpdf)

swift - 如何在 Swift 中的 NSTextView 中实现 NSTextFinderClient 协议(protocol)?