如何使用实用程序 class 中的 NSAlert Sheet 模式
How to use NSAlert Sheet Modal from a Utility class
我正在尝试在 UtilityController Class 中为 NSAlerts 编写一个方法,但该方法没有显示警报。我从我的 ViewController 中的 viewDidAppear() 方法调用它,所以我认为这会起作用,因为视图已经在屏幕上了。对吗?
我从 viewDidAppear() 方法调用它的原因是因为在我的实际应用程序中,我最初从 CoreData 加载数据,它在程序启动时从 viewDidAppear() 方法调用并将该数据与数据进行比较磁盘上的文件。如果在比较过程中加载时检测到不一致,我想给用户一个选择是继续加载更改的数据,还是退出应用程序并修复需要修复的内容。
import Cocoa
class ViewController: NSViewController {
let utility = UtilityController()
let dataController = DataController() // <-- EDIT
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func viewDidAppear() {
super.viewDidAppear() // <-- EDIT
dataController.fetchData() // <-- EDIT
}
override var representedObject: Any? {
didSet {
// Update the view, if already loaded.
}
}
}
import Cocoa
class UtilityController: NSObject {
func showAlert() {
let alert = NSAlert()
// Create an alert notification based upon what was discovered.
alert.messageText = "Warning: This is an alert!"
alert.informativeText = "Something informative will be here!"
alert.addButton(withTitle: "Continue")
alert.addButton(withTitle: "Exit")
if let mainViewWindow = NSApplication.shared.keyWindow?.contentViewController?.view.window {
alert.beginSheetModal(for: mainViewWindow) { (returnCode: NSApplication.ModalResponse) -> Void in
// Continue = 1000
// Exit = 1001
alert.window.close()
switch returnCode.rawValue {
case 1001: // Exit
exit(0)
default: // Continue
return
}
}
}
}
}
编辑:我添加了这个 class,这是我在原来的 post
中遗漏的
import Cocoa
class DataController: NSObject {
// This is the controller class that performs CoreData CRUD
let utility = UtilityController()
func fetchData() {
// do the CoreData fetch of the data and if an error is found
utility.showAlert()
}
}
扩展 NSViewController
并使 showAlert
成为它的实例方法会容易得多。这样您就可以访问调用此方法的视图控制器的视图控制器的 view.window
属性 。注意不要忘记在覆盖 viewDidAppear
方法时调用 super
。请注意,如果您构建并 运行 您的应用程序(这只是从 Xcode 中 运行 宁您的应用程序的问题),您的方法应该有效,但请注意,如果您的应用程序可能会失败,则您的方法可能会失败执行该代码时未激活。使用视图控制器的 view.window
属性 更安全:
extension NSViewController {
func showAlert() {
let alert = NSAlert()
alert.messageText = "Warning: This is an alert!"
alert.informativeText = "Something informative will be here!"
alert.addButton(withTitle: "Continue")
alert.addButton(withTitle: "Exit")
if let window = view.window {
alert.beginSheetModal(for: window) { modalResponse in
alert.window.close()
switch modalResponse.rawValue {
case 1001: // Exit
exit(0)
default: // Continue
return
}
}
}
}
}
用法:
class ViewController: NSViewController {
override func viewDidAppear() {
super.viewDidAppear()
showAlert()
}
}
edit/update:
如果您不想扩展 NSViewController,最安全的方法是在调用您的方法时传递 window:
class ViewController: NSViewController {
let utility = UtilityController()
let dataController = DataController()
override func viewDidAppear() {
super.viewDidAppear()
dataController.fetchData(view.window)
}
}
class UtilityController: NSObject {
func showAlert(_ sender: NSWindow?) {
guard let sender = sender else { return }
let alert = NSAlert()
alert.messageText = "Warning: This is an alert!"
alert.informativeText = "Something informative will be here!"
alert.addButton(withTitle: "Continue")
alert.addButton(withTitle: "Exit")
alert.beginSheetModal(for: sender) { modalResponse in
alert.window.close()
switch modalResponse.rawValue {
case 1001:
exit(0)
default:
return
}
}
}
}
import Cocoa
class DataController: NSObject {
let utility = UtilityController()
func fetchData(_ sender: NSWindow?) {
utility.showAlert(sender)
}
}
我正在尝试在 UtilityController Class 中为 NSAlerts 编写一个方法,但该方法没有显示警报。我从我的 ViewController 中的 viewDidAppear() 方法调用它,所以我认为这会起作用,因为视图已经在屏幕上了。对吗?
我从 viewDidAppear() 方法调用它的原因是因为在我的实际应用程序中,我最初从 CoreData 加载数据,它在程序启动时从 viewDidAppear() 方法调用并将该数据与数据进行比较磁盘上的文件。如果在比较过程中加载时检测到不一致,我想给用户一个选择是继续加载更改的数据,还是退出应用程序并修复需要修复的内容。
import Cocoa
class ViewController: NSViewController {
let utility = UtilityController()
let dataController = DataController() // <-- EDIT
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func viewDidAppear() {
super.viewDidAppear() // <-- EDIT
dataController.fetchData() // <-- EDIT
}
override var representedObject: Any? {
didSet {
// Update the view, if already loaded.
}
}
}
import Cocoa
class UtilityController: NSObject {
func showAlert() {
let alert = NSAlert()
// Create an alert notification based upon what was discovered.
alert.messageText = "Warning: This is an alert!"
alert.informativeText = "Something informative will be here!"
alert.addButton(withTitle: "Continue")
alert.addButton(withTitle: "Exit")
if let mainViewWindow = NSApplication.shared.keyWindow?.contentViewController?.view.window {
alert.beginSheetModal(for: mainViewWindow) { (returnCode: NSApplication.ModalResponse) -> Void in
// Continue = 1000
// Exit = 1001
alert.window.close()
switch returnCode.rawValue {
case 1001: // Exit
exit(0)
default: // Continue
return
}
}
}
}
}
编辑:我添加了这个 class,这是我在原来的 post
中遗漏的import Cocoa
class DataController: NSObject {
// This is the controller class that performs CoreData CRUD
let utility = UtilityController()
func fetchData() {
// do the CoreData fetch of the data and if an error is found
utility.showAlert()
}
}
扩展 NSViewController
并使 showAlert
成为它的实例方法会容易得多。这样您就可以访问调用此方法的视图控制器的视图控制器的 view.window
属性 。注意不要忘记在覆盖 viewDidAppear
方法时调用 super
。请注意,如果您构建并 运行 您的应用程序(这只是从 Xcode 中 运行 宁您的应用程序的问题),您的方法应该有效,但请注意,如果您的应用程序可能会失败,则您的方法可能会失败执行该代码时未激活。使用视图控制器的 view.window
属性 更安全:
extension NSViewController {
func showAlert() {
let alert = NSAlert()
alert.messageText = "Warning: This is an alert!"
alert.informativeText = "Something informative will be here!"
alert.addButton(withTitle: "Continue")
alert.addButton(withTitle: "Exit")
if let window = view.window {
alert.beginSheetModal(for: window) { modalResponse in
alert.window.close()
switch modalResponse.rawValue {
case 1001: // Exit
exit(0)
default: // Continue
return
}
}
}
}
}
用法:
class ViewController: NSViewController {
override func viewDidAppear() {
super.viewDidAppear()
showAlert()
}
}
edit/update:
如果您不想扩展 NSViewController,最安全的方法是在调用您的方法时传递 window:
class ViewController: NSViewController {
let utility = UtilityController()
let dataController = DataController()
override func viewDidAppear() {
super.viewDidAppear()
dataController.fetchData(view.window)
}
}
class UtilityController: NSObject {
func showAlert(_ sender: NSWindow?) {
guard let sender = sender else { return }
let alert = NSAlert()
alert.messageText = "Warning: This is an alert!"
alert.informativeText = "Something informative will be here!"
alert.addButton(withTitle: "Continue")
alert.addButton(withTitle: "Exit")
alert.beginSheetModal(for: sender) { modalResponse in
alert.window.close()
switch modalResponse.rawValue {
case 1001:
exit(0)
default:
return
}
}
}
}
import Cocoa
class DataController: NSObject {
let utility = UtilityController()
func fetchData(_ sender: NSWindow?) {
utility.showAlert(sender)
}
}