Improving Scrolling Performance of Circles on iOS

Hint: Don’t use view.layer.cornerRadius.

Circular avatars are all the rage lately, with even Apple adopting them for contacts in iOS 7.

There’s a very easy way to make a circle from a UIImageView (and in fact, any UIView).

// ...
    [self.imageView setImage:user.avatarImage];
    [self.imageView.layer setCornerRadius:view.frame.size.width/2];
// ...

However, this is very slow if you’re planning to use it for something like a list of avatars in a UITableView. You’ll notice jittering/stuttering even on an iPhone 5.

A much faster way is by masking the image.

// ...
    [imageView setImage:[self maskedAvatarFromImage:user.avatarImage]];
// ...

- (UIImage *)maskedAvatarFromImage:(UIImage *)image {

    // set up the drawing context
    CGRect imageRect = CGRectMake(0, 0, image.size.width, image.size.height);
    UIGraphicsBeginImageContextWithOptions(imageRect.size, NO, 0);

    // set up a path to mask/clip to, and draw it.
    UIBezierPath *circlePath = [UIBezierPath bezierPathWithOvalInRect:imageRect];
    [circlePath addClip];
    [image drawInRect:imageRect];

    // get a UIImage from the image context
    UIImage *maskedImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return maskedImage;
}

You could also use an image asset as a mask, but I haven’t found that there’s a significant performance difference between the two.

SmoothAnchors jQuery plugin

Most web browsers now use smooth scrolling when you hit spacebar or use the page up/down shortcuts. I like this behaviour because it helps you keep your bearings as you navigate through a page — but for some reason modern web browsers don’t animate to internal anchor locations and insist on skipping straight to them.

To extend this to anchor links, I’ve written a jQuery plugin to easily add smooth scrolling to all anchored locations on a page with no need to make any changes to your markup.

The plugin is really easy to use. You just include the .js file and initialise the plugin like this:

<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="SmoothAnchors.js"></script>
<script type="text/javascript">
    $(document).ready(function() {
        $().SmoothAnchors();
    });
</script>

If you’re using jQuery 1.7+, the plugin will use the jQuery .on() function to work with links that have been added after the plugin has been initialised (i.e. if you’re dynamically adding content to your page).