Skip to main content

Getting "Using two-stage rotation animation” warning with UIImagePickerController



I wrote simple code to test UIImagePickerController:







@implementation ProfileEditViewController



- (void)viewDidLoad {

[super viewDidLoad];



photoTaker_ = [[UIImagePickerController alloc] init];

photoTaker_.delegate = self;

photoTaker_.sourceType = UIImagePickerControllerSourceTypeCamera;

photoTaker_.showsCameraControls = NO;

}



- (void)viewDidAppear: (BOOL)animated {

[self presentModalViewController: photoTaker_ animated: NO];

}



@end







And I'm getting strange warnings like the following:







2010-05-20 17:53:13.838 TestProj[2814:307] Using two-stage rotation animation. To use the smoother single-stage animation, this application must remove two-stage method implementations. 2010-05-20 17:53:13.849 TestProj[2814:307] Using two-stage rotation animation is not supported when rotating more than one view controller or view controllers not the window delegate







Got any idea what this is about? Thanks a lot in advance!


Comments

  1. This message will appear if you are presenting the UIImagePickerController within another UIViewController. Because it isn't pushed like a UINavigationController stack, there is confusion at the UIWindow level. I don't know if the warning is a problem, but to eliminate the warning you can do the following:

    // self = a UIViewController
    //

    - (void) showCamera
    {
    cameraView = [[UIImagePickerController alloc] init];
    [[[UIApplication sharedApplication] keyWindow] setRootViewController:cameraView];
    [self presentModalViewController:cameraView animated:NO];
    }

    - (void) removeCamera
    {
    [[[UIApplication sharedApplication] keyWindow] setRootViewController:self];
    [self dismissModalViewControllerAnimated:NO];
    [cameraView release];
    }

    ReplyDelete
  2. Perhaps you are adding the root UIViewController's view as a subview of the window instead of assigning the view controller to the window's rootController property?

    ReplyDelete
  3. You may be trying to present two modal view controllers at the same time, and they are fighting for animation resources.

    1) There is rarely any UI reason to do this. You could instead just go directly to the second view controller (the image picker); and, after dismissing it, then present the first view or view controller.

    2) If you do want two stacked view controllers or a view controller on top of a view, then set a timer in viewDidAppear to present the second view controller after the first one has finished it's animation. (You could display a dummy png image of a blank picker in the first one to prevent too much display flashing until the second view controller goes live.)

    EDIT - Added a random code example:

    I might try substituting this as an experiment:

    - (void)foo {
    [self presentModalViewController: photoTaker_ animated: NO];
    }

    - (void)viewDidAppear: (BOOL)animated {
    NSTimer *bar = [ NSTimer scheduledTimerWithTimeInterval: (2.0f)
    target: self
    selector: @selector(foo)
    userInfo: nil
    repeats:NO ];
    }


    A shorter time delay may work as well.

    ReplyDelete
  4. IT ALL FALLS BACK ON THE UI

    This warning can be implemented for several different objects: Pickers, keyboard, etc.

    I have found that it is related to the UI taking two steps to complete a transition or other animation. Or for any instance where the UI is trying to finish one thing and is being asked to execute another before it has finished. (therefore it covers a wide range of possible triggers)

    I have seen the warning appear on 4.0 & 4.2. In my case I was working with rotating the device and catching whether the keyboard was still up-(i.e. text field was still first responder). If so, the keyboard needed to stay up for between the views, but this presented other complications with other views.

    Therefore, I implemented a BOOL tracker to keep track if keybaordIsPresent, and if so I was {textfield resignFirstResponder]; when detecting the orientation change and the reset the textfield to becomeFristResponder after the transition that was wrapped in an Animation Block. My BOOL tracker worked better, I still use the NSNotifications for the Keyboard, but there were overlaps of notifications during rotations because the keyboard was being dismissed without requesting such. The BOOL is set to NO on Load, and when the [textfield resignFirstResponder]; is implemented. *not when "-(void)keyboardWillhide is trigger by the NSNotifications, which gives me both working triggers that never conflict. The BOOL is set to YES, only when the user touches textfield which automatically triggers becomeFirstResponder.

    I removed the warning by taking the [textfild resignFirstResponder]; out of the

    -(void)willAnimateFirstHalfOfRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    //if (keyboardIsPresent == YES) {[self.entryTextField resignFirstResponder];}


    }
    and placing it back at the top of the code for the:

    - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {

    if (keyboardIsPresent == YES) {
    [self.entryTextField resignFirstResponder];
    }

    //Determine Which Orientation is Present:
    if((fromInterfaceOrientation == UIInterfaceOrientationPortrait) || (fromInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)){
    //LANDSCAPE VIEW:
    [self configureLandscapeView];
    }else {
    //PORTRAIT VIEW:
    [self configurePortraitView];
    }


    }


    **Even though I had no code inside the -(void)willAnimatFirstHalfOfRotationToInterface:, the warning was still popping up. I think the warning was still popping up because the compiler still has to attempt the method while it is trying to execute the first animation and therefore gets the double animation call or overlap of resources. It doesn't know that there is no executable code with the method until after it runs through it. And by that time it already set aside resource in preparation for handling possible actions within the method.

    **To ellimiate the warning I had to remove or nil out the code for the willAnimateFirstHalfOfRotation, so that the compiler does not have to even check to see if there is a possible 2nd animation or action that may need to be executed at the same time.

    /*-(void)willAnimateFirstHalfOfRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    //if (keyboardIsPresent == YES) {[self.entryTextField resignFirstResponder];}}*/


    After the transition is completed, within the original animation block I check to see if the "keyboardIsPresent" was YES prior to the rotation, and if so, I resign the First Responder once again. I use setAnimationDuration:0.3which comes out pretty clean and not jumpy.

    ReplyDelete
  5. Well, you are presenting UIImagePickerController modally inside viewDidAppear of ProfileEditViewController.

    Think about this. That means when ProfileEditViewController view appears, the UIImagePickerController appears, say later you dismiss UIImagePickerController and it goes back to ProfileEditViewController, then viewDidAppear is called again and UIImagePickerController appears, say later you dismiss UIImagePickerController and it goes back to ProfileEditViewController, then viewDidAppear is called again and.... you get the idea.

    That warning is rather cryptic though, not sure if that is what it's trying to tell you. I would suggest making a button somewhere on the ProfileEditViewController that calls presentModalViewController and also make sure you have a way to dismiss the UIImagePickerController (I've never used it not sure if it has one automatically).

    ReplyDelete
  6. Same here... bt on the stack indicates that I get an objc_exception_throw in a routine called

    1 0x00517692 in UIImagePickerEnsureViewIsInsidePopover ()

    Not sure if image picker has to open in a popover... are you guys targeting iPad/iPhone or both. I'm working on the iPad.

    ReplyDelete
  7. I think the warning here is about Core Animation performance. As a test, I loaded the image picker without any action sheet or other animations going on and the warnings are still there. I think these are warnings coming from the image picker class itself and not from any misuse of the API.

    ReplyDelete

Post a Comment

Popular posts from this blog

[韓日関係] 首相含む大幅な内閣改造の可能性…早ければ来月10日ごろ=韓国

div not scrolling properly with slimScroll plugin

I am using the slimScroll plugin for jQuery by Piotr Rochala Which is a great plugin for nice scrollbars on most browsers but I am stuck because I am using it for a chat box and whenever the user appends new text to the boxit does scroll using the .scrollTop() method however the plugin's scrollbar doesnt scroll with it and when the user wants to look though the chat history it will start scrolling from near the top. I have made a quick demo of my situation http://jsfiddle.net/DY9CT/2/ Does anyone know how to solve this problem?

Why does this javascript based printing cause Safari to refresh the page?

The page I am working on has a javascript function executed to print parts of the page. For some reason, printing in Safari, causes the window to somehow update. I say somehow, because it does not really refresh as in reload the page, but rather it starts the "rendering" of the page from start, i.e. scroll to top, flash animations start from 0, and so forth. The effect is reproduced by this fiddle: http://jsfiddle.net/fYmnB/ Clicking the print button and finishing or cancelling a print in Safari causes the screen to "go white" for a sec, which in my real website manifests itself as something "like" a reload. While running print button with, let's say, Firefox, just opens and closes the print dialogue without affecting the fiddle page in any way. Is there something with my way of calling the browsers print method that causes this, or how can it be explained - and preferably, avoided? P.S.: On my real site the same occurs with Chrome. In the ex