2011-05-04 86 views
1

新手目标C/Cocoa问题:我有一个应用程序,其中包含一些数据输入字段和一个“执行”按钮。当按下按钮时,会进行一些计算,并将输出数据显示在同一个窗口中的表格视图和一些文本字段中。我想要的是,当按下按钮时,文本字段和表格视图在计算发生时都被清除。Cocoa/Objective C中的更新屏幕按钮按下按钮

我试着做出适当的调用,作为按钮按下的动作例程的前几个语句,但那不起作用。我会想象,在我的操作例程完成之后,运行时不会被调用来执行屏幕更新。

有没有简单的方法来做我想做的事情?谢谢。

回答

2

你的屏幕更新没有发生,直到你的程序完成后才正确。大部分绘图到屏幕上排队以提高性能。

当您更改NSTextField中的值时,它知道要调用[self setNeedsDisplay:YES]以排队重新绘制的需要。如果您想强制显示,可以拨打[textField display]。 (请注意,拨打[textField setNeedsDisplay:YES]不会立即显示)。 NSTableView因为这个-display方法不太可能适用于它,所以事情变得更加困难。

虽然您可以创建一个辅助线程来完成您的处理,但这会产生很多复杂性,可能不值得。您可以考虑使用-performSelector:withObject:afterDelay:开始处理例程而不是直接调用它。

- (IBAction)buttonClicked:(id)sender { 
    [textField setStringValue:@""]; 
    [tableView reloadData]; 
    // instead of doing the following: 
    // [self processData:nil]; 
    // do 
    [self performSelector:@selector(processData:) withObject:nil afterDelay:0.0]; 
} 

- (void)processData:(id)sender { 
    // process the data 

    [textField setStringValue:@"the results"]; 
    [tableView reloadData]; 
} 

使用-performSelector:withObject:afterDelay:是不是直接调用的方法不同,因为它会导致不立即调用的方法,而是按计划将“尽快”之称。在很多情况下,您的应用程序可以在执行该计算方法之前挤入UI的更新。如果测试发现这种情况,那么您可以避免不必要创建辅助线程来执行处理。

+0

来显示结果。这很好,谢谢,除了我需要延迟0.1。我从所有这些答案中学到了很多东西,并希望我可以接受不止一种答案。 – rogerl 2011-05-04 12:19:18

1

如果您想强制更新屏幕,请从您的UIView调用setNeedsDisplay

+1

这有同样的问题。我可以(并确实)在按钮动作例程中为相关控件调用setNeedsDisplay,但是我不认为屏幕更新实际上发生在动作例程返回之前。 – rogerl 2011-05-04 01:30:14

+0

正如我所提到的,textField已经将自己设置为需要显示。你需要强制它使用'-display'显示。 – NSGod 2011-05-04 01:40:20

+0

如果你执行繁重的计算,那么你应该在另一个线程中执行(计算)(在后台执行或创建新线程或NSOperation)。所有更新屏幕任务都在主线程中完成。计算完成后,您可以通过调用performSelectorOnMainThread – Xuvi 2011-05-04 01:40:30

1

我猜想,运行时间 不会被调用做屏幕 更新,直到我的动作例程 结束后。

宾果。您的按钮的操作方法在主线程上调用,该主线程负责更新用户界面。因此,只有在您的操作方法返回后,界面才会更新。

为了解决这个问题,你可以将你的动作方法分成两部分。第一部分将调用清除先前的视图并设置要用于渲染的新状态。第二部分进行新的计算,并转移到自己的方法。然后,在第一部分结束时,添加的东西大致是:

[self performSelectorInBackground:@selector(myActionSecondPart) withObject:nil];

...运行在后台的运算单元。然后你的UI将在计算运行时更新。