objective-cmacoscocoansprogressindicator

Problem with NSProgressIndictor on mojave


I implemented NSProgressIndicator on sierra os and it worked fine in the application on it.However, for testing when i moved the application to high-sierra or mojave, theprogressbaris not displayed at all, while it works fine on sierra

when clicking the button in the application, inside the button function, i initiated the progressbar as follow,

[_progressbar startAnimation:sender];
[_progressbar setHidden:false];

and when i return i change setHidden to true. So, where am i possibly going wrong?

UPDATE: I tried to use the following code,

 //Create the block that we wish to run on a different thread.
    void (^progressBlock)(void);
    progressBlock = ^{

        [_progressbar setDoubleValue:0.0];
        [_progressbar startAnimation:sender];
        [_progressbar setHidden:false];
      //  running = YES; // this is a instance variable


            //NOTE: It is important to let all UI updates occur on the main thread,
            //so we put the following UI updates on the main queue.
            dispatch_async(dispatch_get_main_queue(), ^{

                [_progressbar setNeedsDisplay:YES];
            });

            // Do some more hard work here...


    }; //end of progressBlock
 dispatch_queue_t queue = dispatch_get_global_queue(0,0);
 dispatch_async(queue,progressBlock);

Solution

  • I noticed this problem on my old macOS apps, and if I recall correctly it was after first testing in High Sierra betas, as you just found.

    Most user interface views need the main thread to draw or receive user input. But it seems that, in earlier macOS versions, Apple had done some magic to make NSProgressIndicator display and animate even if the main thread was busy doing other work. Then in recent macOS versions (10.13?), this magic seems to have been removed.

    It never was a good idea to do long-running work on the main thread, since it makes other views in your user interface, which never had the NSProgressIndicator magic, unresponsive to the user. I think Apple figured that since we're all multi-threaders now with Dispatch (also called Grand Central Dispatch), it was time to remove the magic, which was probably difficult for them to maintain. I'd always found it to be somewhat buggy and unreliable.

    So the answer is that you need to get whatever work that progress indicator is tracking off of the main thread. You will probably be using dispatch_async() and friends, although NSOperation and NSOperationQueue still work and will also do the job.