NSProgressIndicator in NSMenuItem not updating on

2019-02-27 11:57发布

问题:

I've got a NSMenu attached to a NSStatusItem (a menu bar application). While downloading a file I want to display a NSProgressIndicator in an item of this menu. I've created a NSViewController subclass for this progress indicator with the following properties:

@property NSUInteger current; // Bound to NSProgressIndicator value
@property NSString *status;   // Bound to a NSTextField value
@property NSUInteger total;   // Bound to NSProgressIndicator max value

When needed I start the download of the file with the following code, which runs in NSRunLoopCommonModes so that the delegate methods are also called when the NSMenu is displayed (which runs in NSEventTrackingRunLoopMode):

NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
[connection scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
[connection start];

In the didReceiveData delegate method I then set the properties on my NSViewController subclass:

progressViewController.current = receivedData.length;
progressViewController.status = @"Downloading...";
progressViewController.total = expectedBytes;

This works great if I bind the properties to a label, but the NSProgressIndicator only updates if I open the menu before the connection is started, and don't close it again until the download is finished. But if I open it afterwards, the progress indicator doesn't update. It shows the value the properties had at the moment I opened the menu, but this value doesn't update. The progress indicator then isn't animated either. Note that labels do work...

I tried to manually call setNeedsDisplay with YES and call display om on both the custom view and the progress indicator when I change the values, but that doesn't work. The only thing that does fix the progress indicator is calling [progress setHidden:YES]; [progress setHidden:NO]; in rapid succession, but that causes the progress indicator to flicker, and is of course a bad solution.

What am I doing wrong? How can I fix this NSProgressIndicator?

回答1:

I had the same problem and this answer solved my problem: https://stackoverflow.com/a/4692194/406677

In swift:

progressIndicator.performSelector("startAnimation:", withObject:self, afterDelay: 0.0, inModes: [NSEventTrackingRunLoopMode])