There is no solution that does not require you to ... a) mix up with the internal elements of the NSProgressIndicator or
b) Roll Your Own β’.
So, I would say that you have to write down the error.
At least on OS X 10.6.5 and higher, as soon as you set the wantsLayer property with an indefinite progress indicator YES , the animation will stop immediately - you can check it for yourself with a reduced test version, application (code below).
The animate: method (deprecated since 10.5) was called, which you could call NSProgressIndicator , which might help you (see Using Undefined Progress Indicators ).
Edit:
animate: call animate: followed by displayIfNeeded ( Change 2: as Brent noted, this is redundant) from the timer still works. βMaybeβ simply meant that I did not know if the use of the deprecated APIs in the App Store was authorized, or if that was relevant to you at all.
Application example
A simple Cocoa application with one controller:
@interface ProgressTester : NSObject { NSProgressIndicator *indicator; } @property (nonatomic, assign) IBOutlet NSProgressIndicator *indicator; @property (nonatomic, assign, getter=isLayered) BOOL layered; - (IBAction)toggleWantsLayer:(id)sender; @end @implementation ProgressTester @synthesize indicator; @dynamic layered; - (BOOL)isLayered { return [indicator wantsLayer]; } - (void)setLayered:(BOOL)wantsLayer { static NSString *layeredKey = @"layered"; [self willChangeValueForKey:layeredKey]; [indicator setWantsLayer:wantsLayer]; [self didChangeValueForKey:layeredKey]; } - (void)awakeFromNib {
In the NIB:
- Controller instances
- one NSProgressIndicator with a standard index (connected to the controller
indicator output) - button with controller as target and
toggleWantsLayer: as action
Added Brent:
I used the information in this answer to write a simple subclass of NSProgressIndicator:
http://www.pastie.org/1465755 http://www.pastie.org/1540277
Note that in my tests, the -animate: call worked fine without -displayIfNeeded .
Feel free to use it as you wish. I would love to hear from you if you use it, though!
Added by Daniel:
A few points about subclassing on pastie:
initWithFrame: should go to initWithFrame: instead of init ( Change 3 : fixed in the updated fragment).The timer does not need to be saved:
NSTimer calls the associated runloop with retain and does not delete it until the timer invalidate d ( Change 3 : fixed).There is a strong candidate for saving a timer loop: since NSTimer maintains its purpose , dealloc will probably never be called if the indicator is released during animation through a timer (I know this is an extreme case, but ...) ( Change 3 : also took care).I'm not quite sure, but I think that the implementation of awakeFromNib redundant, since KVO configuration has already occurred in initWithFrame: ( Change 3 : clarified in the updated fragment).
However, I personally would prefer not to synthesize animationTimer and handle the timer invalidation in the installer to completely get rid of the KVO stuff. (Observing self bit outside of my comfort zone.)
Posted by Ann:
Adding a snippet from the last paste link for archiving purposes:
ArchProgressIndicator.h
// // ArchProgressIndicator.h // Translate2 // // Created by Brent Royal-Gordon on 1/15/11. // Copyright 2011 Architechies. All rights reserved. // #import <Cocoa/Cocoa.h> @interface ArchProgressIndicator : NSProgressIndicator { @private NSTimer * animationTimer; } // Just like NSProgressIndicator, but works better in a layer-backed view. @end
ArchProgressIndicator.m
// // ArchProgressIndicator.m // Translate2 // // Created by Brent Royal-Gordon on 1/15/11. // Copyright 2011 Architechies. All rights reserved. //