Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 如何强制NSTextField标签刷新_Objective C_Macos_Cocoa_Nstextfield - Fatal编程技术网

Objective c 如何强制NSTextField标签刷新

Objective c 如何强制NSTextField标签刷新,objective-c,macos,cocoa,nstextfield,Objective C,Macos,Cocoa,Nstextfield,我试图做的事情似乎很简单,但实现起来却让我感到困惑。如何在更改标签的值后强制其刷新 我刚刚创建了一个简单的进度窗口。由于主应用程序正在执行某些操作,我会弹出进度窗口,并希望在循环执行时更新标签和进度条的值 我创建了一个新的NSWindow和XIB文件,其中包含标签和progressbar的出口,我正在加载它: _pbWindow = [[ProgressBar alloc] initWithWindowNibName:@"ProgressBar

我试图做的事情似乎很简单,但实现起来却让我感到困惑。如何在更改标签的值后强制其刷新

我刚刚创建了一个简单的进度窗口。由于主应用程序正在执行某些操作,我会弹出进度窗口,并希望在循环执行时更新标签和进度条的值

我创建了一个新的NSWindow和XIB文件,其中包含标签和progressbar的出口,我正在加载它:

_pbWindow                           = [[ProgressBar alloc] initWithWindowNibName:@"ProgressBar"];

[_pbWindow showWindow:self];
当我打电话时:

_pbWindow.lblProgress1.stringValue = @"Doing this now...";
我无法使标签在新窗口中实际刷新

我在这里和谷歌搜索过,似乎找不到任何东西可以告诉我如何在不同的窗口中执行此操作,只是如果它在主窗口中,它将只是刷新(无论如何,这一直是我的经验)

我想可能是因为窗口没有对焦,所以我试着用模式打开它:

[[NSApplication sharedApplication] beginSheet:[_pbWindow window]
                               modalForWindow:[[NSApplication sharedApplication] mainWindow]
                                modalDelegate:_pbWindow
                               didEndSelector:nil
                                  contextInfo:nil];

但它仍然不起作用。

当您设置文本字段的
stringValue
时,文本字段会将自身标记为需要显示(其中一个
-setNeedsDisplay…
方法)。它不会立即显示自己。稍后,在主事件循环期间,应用程序将告诉其每个窗口显示所需的,并且文本字段的新内容将实际绘制在屏幕上

但是,由于您处于一个长期运行的循环中,因此不允许运行主事件循环,并且如果需要,windows也没有机会显示

一种解决方法是在更改文本字段的
stringValue
后,直接在文本字段上调用
-displayIfNeeded

_pbWindow.lblProgress1.stringValue = @"Doing this now...";
[_pbWindow.lblProgress1 displayIfNeeded];
但是,不让主事件循环运行还有其他问题。仅仅解决这一个问题仍然会留下其他问题。例如,您的应用程序将在“活动监视器”中显示为无响应,当鼠标悬停在其窗口上时,系统将显示旋转的色轮光标。你应该考虑找到另一种方法来构造你的应用程序。 例如,您可以在主线程上以模式窗口的形式运行进度窗口(使用
-[NSApplication runModalForWindow://code>),并在后台线程上执行该工作。工作完成后,调用
-[NSApplication stopModal…]
方法或
-[NSApplication abortModal]
(但请阅读文档,了解在什么情况下应该使用哪种方法,尽管在10.9中取消了对
-stopModal…
的一些限制)。主线程将被允许返回到主事件循环,但是模式窗口将阻止用户对UI的其余部分执行任何在操作进行时不允许他们执行的操作

或者,也许操作不应该垄断你的整个应用程序。也许它应该是单一窗口的模态。在这种情况下,您可以将进度窗口显示为窗口上的工作表,该窗口应在操作期间禁用。使用
-[NSWindow beginSheet:completionHandler:][/code>开始工作表,并在后台启动操作。操作完成后,在主线程上调用一个
-[NSWindow endSheet:…]
方法


如果您在后台线程上运行该工作,请务必使用GCD和
dispatch\u get\u main\u queue()
-performSelectorOnMainThread:…

将影响GUI的任何更改分流到主线程,非常感谢您提供了一个精彩的答案!这两种解决方案都能很好地工作,所以我不确定最终会使用哪种解决方案,但目前我正在使用DisplayIfRequired方法来查看这是否满足了需要。