Wednesday, 24 June 2009

Improve iPhone flip transition performance

If you've tried animating a UIView onto the screen using UIViewAnimationTransitionFlipFromLeft or UIViewAnimationTransitionFlipFromRight you may have noticed a slight lag in the first animation. The obvious way to implement a flip transition is with code like the following:

- (void)showFlipView {
    UIView *parentView = self.view;

    self.flipViewController.view.frame = parentView.bounds;

    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft
                           forView:parentView
                             cache:YES];

    [UIView setAnimationDuration:1];
    [parentView addSubview:self.flipViewController.view];
    [UIView commitAnimations];
}

One explanation for the lag you sometimes see is that views are lazy loaded, and the delay is caused by the flip view being loaded. But even if you force the view to be loaded by accessing the controller's view property this lag can still manifest.

One way I found to stop this lag is to add the flip view to the parent view when the parent view loads, and set its hidden value to YES. Then when you want to animate it in, you set hidden to NO:


- (void)viewDidLoad {
    [super viewDidLoad];

    // ...

    self.flipViewController.view.hidden = YES;
    [self.view addSubview:self.flipViewController.view];
}

- (void)showFlipView {
    UIView *parentView = self.view;

    self.flipViewController.view.frame = parentView.bounds;

    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft
                           forView:parentView
                             cache:YES];

    [UIView setAnimationDuration:1];
    self.flipViewController.view.hidden = NO;
    [UIView commitAnimations];
}

Thursday, 11 June 2009

XCode trailing whitespace

For all the other trailing-whitespace-haters out there, if you would like to remove trailing whitespace from all the files in your XCode project, do a global search replace (Shift+⌘+F) for the following regular expression:

[ \t]+$

In older versions of XCode you have to select all the results before hitting "Replace".

UIWebView doesn't open target="_blank" links.

If you are using UIImageView to display external webpages, you may come across an issue where certain links don't fire UIWebViewNavigationTypeLinkClicked events. This happens when the link has the target="_blank" attribute.

To work around this problem you can inject some javascript after the page load to remove this attribute from all the links:

- (void)webViewDidFinishLoad:(UIWebView *)webView {
        NSString *js = @"\
        var d = document.getElementsByTagName('a');\
        for (var i = 0; i < d.length; i++) {\
            if (d[i].getAttribute('target') == '_blank') {\
                d[i].removeAttribute('target');\
            }\
        }\
        ";

        [webView stringByEvaluatingJavaScriptFromString:js];
}