how to display UIActivityIndicatorView BEFORE rotation begins

前端 未结 4 1954
既然无缘
既然无缘 2020-12-12 06:33

I\'d like to display an activity indicator BEFORE the work undertaken by willAnimateRotationToInterfaceOrientation:duration: begins. Most of the time in my

相关标签:
4条回答
  • 2020-12-12 06:58

    The app doesn't update the screen to show the UIActivityIndicatorView until the main run loop regains control. When a rotation event happens, the willRotate... and willAnimateRotation... methods are called in one pass through the main run loop. So you block on the hard work method before displaying the activity indicator.

    To make this work, you need to push the hard work over to another thread. I would put the call to the hard work method in the willRotate... method. That method would call back to this view controller when the work is completed so the view can be updated. I would put show the activity indicator in the willAnimateRotation... method. I wouldn't bother with a didRotateFrom... method. I recommend reading the Threaded Programming Guide.

    Edit in response to a comment: You can effectively block user interaction by having the willAnimateRotation... method put a non functioning interface on screen such as a view displaying a dark overlay over and the UIActivityIndicatorView. Then when the heavy lifting is done, this overlay is removed, and the interface becomes active again. Then the drawing code will have the opportunity to properly add and animate the activity indicator.

    0 讨论(0)
  • 2020-12-12 07:14

    Either execute the heavy lifting in a background thread and post the results in the foreground thread to update the UI (UIKit is only thread safe since iOS 4.0):

    [self performSelectorInBackground:@selector(simulateHardWorkNeededToGetDisplayInShapeBeforeRotation) withObject:nil]
    

    Or you can schedule the heavy lifting method to be executed after the rotation took place:

    [self performSelector:@selector(simulateHardWorkNeededToGetDisplayInShapeBeforeRotation) withObject:nil afterDelay:0.4]
    

    But these are only hacks and the real solution is to have proper background processing if your UI needs heavy processing to get updated, may it be in portrait or landscape. NSOperation and NSOperationQueue is a good place to start.

    0 讨论(0)
  • 2020-12-12 07:16

    Try performing you work on a second thread after showing the activity view.

    [self showActivityIndicatorView];
    [self performSelector:@selector(simulateHardWorkNeededToGetDisplayInShapeBeforeRotation) withObject:nil afterDelay:0.01];
    
    0 讨论(0)
  • 2020-12-12 07:21

    More digging (first in Matt Neuberg's Programming iPhone 4) and then this helpful question on forcing Core Animation to run its thread from stackoverflow and I have a solution that seems to be working well. Both Neuberg and Apple issue strong caution about this approach because of the potential for unwelcome side effects. In testing so far, it seems to be OK for my particular case.

    Changing the code above as follows implements the change. The key addition is [CATransaction flush], forcing the UIActivityIndicatorView to start displaying even though the run loop won't be ended until after the willAnimateRotationToInterfaceOrientation:duration method completes.

    - (void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration;
    {
        NSLog(@"willRotate");
    
        [self showActivityIndicatorView];
        [CATransaction flush];  // this starts the animation right away, w/o waiting for end of the run loop
    }
    
    - (void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration;
    {
        NSLog(@"willAnimateRotation");
        [self simulateHardWorkNeededToGetDisplayInShapeBeforeRotation];
        [self hideActivityIndicatorView];
    }
    
    
    - (void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation;
    {
        NSLog(@"didRotate");
    }
    
    0 讨论(0)
提交回复
热议问题