问题
I'm trying to use a NSProgressIndicator (indeterminate) inside of a statusbar-menu. I'm using an NSView-object as view for the menuitem, and then subviews the progress indicator to display it. But whenever i try to call the startAnimation: for the progress, nothing happens. When i try do the very same thing on a normal NSWindow it works perfectly, just not when inside a menuitem.
I'm new to both cocoa and objective-c so I might've overlooked something "obvious" but I've searched quite a bit for a workaround but without success. I found something about menuitems cant be updated while shown and that you need to use a bordeless window instead. But I have not been able to confirm this in any documentation.
Edit:
Ok, almost works now. When using the setUsesThreadedAnimation: and from a MenuDelegate's menuWillOpen and creating a new thread. This thread runs a local method:
-(void) doWork(NSProgressIndicator*) p{
[p startAnimation:self];
}
This will start the progressindicator on a random(?) basis when opening the menu. If I call startAnimation:
directly without going through doWork:
(still using a new thread), it never works. Doesn't setUsesThreadedAnimation:
make the progress-bar create it's own thread for the animation?
回答1:
Solved it by using:
[progressIndicator performSelector:@selector(startAnimation:)
withObject:self
afterDelay:0.0
inModes:[NSArray
arrayWithObject:NSEventTrackingRunLoopMode]];
Inside the menuWillOpen:, the problem seems to have been calling startAnimation: before the progressbar was finished drawing itself.
回答2:
How are you referencing the NSProgressIndicator
that is in the view (and the one in the window, for that matter)? For example, do you have a controller class that has IBOutlet
's hooked up to the progress indicators? If you are using an IBOutlet
, are you sure it's hooked up properly in the nib file?
Also, where and when are you calling startAnimation:
? (We need to see some code).
One thing that can sometimes happen is that you forget to hook up an IBOutlet
in the nib. Then, when you attempt to tell the object to do something in code at runtime, the IBOutlet
is nil
, and so what you think is a message being sent to your object is in fact, a message being sent to nil
. In other words, it's just ignored, and effectively looks like it's not working.
Provided you do have a (potentially) valid reference to the UI object, the other common issue you'll see is when a developer is trying to send a message to the object at "too early" of a time. In general, init
methods are too early in the controller object's lifetime to be able to send messages to user interface objects—those IBOutlet
's are still nil
. By the time -awakeFromNib
is called, IBOutlet
's should be valid (provided you hooked them up in IB) and you can then send the message to the UI object.
回答3:
Have you told it to use threaded animation via -setUsesThreadedAnimation:?
来源:https://stackoverflow.com/questions/4671017/using-nsprogressindicator-inside-an-nsmenuitem