以编程方式关闭 sheet
Closing a sheet programmatically
我有几个进程可能需要几秒钟才能完成,我想在我的主应用程序 window 中打开一个 sheet 显示一个不确定的 ProgressWheel 和一条消息说进程进展中。我希望 sheet 在进程完成后关闭。
我试图通过对 sheet 执行 segue 并在我的 prepare(for segue) 中向它发送两个字符串值来实现它——一个 waitingMessage,因此 sheet 可以显示名称正在进行的过程的状态,以及一个 waitingState... 要么是“开始”,要么是“结束”。当我的 sheet ViewController 收到“开始”状态时,它只会显示 ProgressWheel 和消息,而当它收到“结束”状态时,它会自动关闭。
这是我正在尝试的方法,但 sheet 不会关闭,即使它收到“结束”消息 – 它只是显示,整个应用程序不会继续。
import Cocoa
class WaitingViewController: NSViewController {
@IBOutlet weak var waitingProgressWheel: NSProgressIndicator!
@IBOutlet weak var waitingMessageLabel: NSTextField!
var waitingMessage : String = ""
var waitingState : String = ""
override var representedObject: Any? {
didSet {
let incomming = representedObject as! (String, String)
waitingMessage = incomming.0
waitingState = incomming.1
}
}
override func viewDidLoad() {
super.viewDidLoad()
waitingProgressWheel.startAnimation(self)
waitingMessageLabel.stringValue = waitingMessage
if waitingState == "ending" {
waitingProgressWheel.stopAnimation(self)
waitingMessageLabel.stringValue = "Done."
dismiss(self)
}
}
}
这是我准备的相关部分(用于 segue)
override func prepare(for segue: NSStoryboardSegue, sender: Any?) {
if segue.identifier == "waiting" {
var waitingInfo : (String, String) = ("","")
waitingInfo.0 = waitingSegueMessage
waitingInfo.1 = waitingSegueState
(segue.destinationController as! WaitingViewController).representedObject = waitingInfo
}
}
这是我更新的 sheet 视图控制器:
import Cocoa
class WaitingViewController: NSViewController {
@IBOutlet weak var waitingProgressWheel: NSProgressIndicator!
@IBOutlet weak var waitingMessageLabel: NSTextField!
var processWaitingMessage : String = ""
var processWaitingState : ViewController.waitingState = .beginning
var isDone : Bool? {
didSet {
if isDone! {
dismiss(self)
}
}
}
override var representedObject: Any? {
didSet {
let incomming = representedObject as! (String, ViewController.waitingState)
processWaitingMessage = incomming.0
processWaitingState = incomming.1
if processWaitingState == .ending {
isDone = true
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
waitingProgressWheel.startAnimation(self)
waitingMessageLabel.stringValue = processWaitingMessage
if processWaitingState == .ending {
waitingProgressWheel.stopAnimation(self)
waitingMessageLabel.stringValue = "Done."
}
}
}
你的做法是错误的。
您必须从呈现视图控制器更新状态。要做到这一点,您需要一个参考。
在ViewController
中添加一个属性
weak var waitingSheet : WaitingViewController?
在WaitingViewController
中添加一个函数
func updateState(_ state: ViewController.waitingState) {
switch state {
case .beginning:
waitingProgressWheel.startAnimation(self)
waitingMessageLabel.stringValue = "Beginning"
case .ending:
waitingProgressWheel.stopAnimation(self)
waitingMessageLabel.stringValue = "Ending"
case .isDone:
dismiss(self)
}
}
在viewDidLoad
更新状态为beginning
override func viewDidLoad() {
super.viewDidLoad()
updateState(.beginning)
}
返回 ViewController
将 sheet 的引用分配给 prepareForSegue
中的 waitingSheet
(不需要预定义的 representedObject
)
override func prepare(for segue: NSStoryboardSegue, sender: Any?) {
if segue.identifier == "waiting" {
waitingSheet = segue.destinationController as? WaitingViewController
}
}
并从 ViewController
中的任意位置更新状态
waitingSheet?.updateState(.ending)
和
waitingSheet?.updateState(.isDone)
弱 属性 在 sheet 被释放后将自己设置为 nil
我有几个进程可能需要几秒钟才能完成,我想在我的主应用程序 window 中打开一个 sheet 显示一个不确定的 ProgressWheel 和一条消息说进程进展中。我希望 sheet 在进程完成后关闭。
我试图通过对 sheet 执行 segue 并在我的 prepare(for segue) 中向它发送两个字符串值来实现它——一个 waitingMessage,因此 sheet 可以显示名称正在进行的过程的状态,以及一个 waitingState... 要么是“开始”,要么是“结束”。当我的 sheet ViewController 收到“开始”状态时,它只会显示 ProgressWheel 和消息,而当它收到“结束”状态时,它会自动关闭。
这是我正在尝试的方法,但 sheet 不会关闭,即使它收到“结束”消息 – 它只是显示,整个应用程序不会继续。
import Cocoa
class WaitingViewController: NSViewController {
@IBOutlet weak var waitingProgressWheel: NSProgressIndicator!
@IBOutlet weak var waitingMessageLabel: NSTextField!
var waitingMessage : String = ""
var waitingState : String = ""
override var representedObject: Any? {
didSet {
let incomming = representedObject as! (String, String)
waitingMessage = incomming.0
waitingState = incomming.1
}
}
override func viewDidLoad() {
super.viewDidLoad()
waitingProgressWheel.startAnimation(self)
waitingMessageLabel.stringValue = waitingMessage
if waitingState == "ending" {
waitingProgressWheel.stopAnimation(self)
waitingMessageLabel.stringValue = "Done."
dismiss(self)
}
}
}
这是我准备的相关部分(用于 segue)
override func prepare(for segue: NSStoryboardSegue, sender: Any?) {
if segue.identifier == "waiting" {
var waitingInfo : (String, String) = ("","")
waitingInfo.0 = waitingSegueMessage
waitingInfo.1 = waitingSegueState
(segue.destinationController as! WaitingViewController).representedObject = waitingInfo
}
}
这是我更新的 sheet 视图控制器:
import Cocoa
class WaitingViewController: NSViewController {
@IBOutlet weak var waitingProgressWheel: NSProgressIndicator!
@IBOutlet weak var waitingMessageLabel: NSTextField!
var processWaitingMessage : String = ""
var processWaitingState : ViewController.waitingState = .beginning
var isDone : Bool? {
didSet {
if isDone! {
dismiss(self)
}
}
}
override var representedObject: Any? {
didSet {
let incomming = representedObject as! (String, ViewController.waitingState)
processWaitingMessage = incomming.0
processWaitingState = incomming.1
if processWaitingState == .ending {
isDone = true
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
waitingProgressWheel.startAnimation(self)
waitingMessageLabel.stringValue = processWaitingMessage
if processWaitingState == .ending {
waitingProgressWheel.stopAnimation(self)
waitingMessageLabel.stringValue = "Done."
}
}
}
你的做法是错误的。
您必须从呈现视图控制器更新状态。要做到这一点,您需要一个参考。
在ViewController
中添加一个属性
weak var waitingSheet : WaitingViewController?
在WaitingViewController
中添加一个函数
func updateState(_ state: ViewController.waitingState) {
switch state {
case .beginning:
waitingProgressWheel.startAnimation(self)
waitingMessageLabel.stringValue = "Beginning"
case .ending:
waitingProgressWheel.stopAnimation(self)
waitingMessageLabel.stringValue = "Ending"
case .isDone:
dismiss(self)
}
}
在viewDidLoad
更新状态为beginning
override func viewDidLoad() {
super.viewDidLoad()
updateState(.beginning)
}
返回 ViewController
将 sheet 的引用分配给 prepareForSegue
中的 waitingSheet
(不需要预定义的 representedObject
)
override func prepare(for segue: NSStoryboardSegue, sender: Any?) {
if segue.identifier == "waiting" {
waitingSheet = segue.destinationController as? WaitingViewController
}
}
并从 ViewController
waitingSheet?.updateState(.ending)
和
waitingSheet?.updateState(.isDone)
弱 属性 在 sheet 被释放后将自己设置为 nil