This blog has moved
April 22nd, 2008This blog has moved to the following address:
This blog has moved to the following address:
In my previous post I published some sample code on how to use a mask on a core animation layer. Here is a practical example of a mask, creating a scroll control almost identical to the one displayed in iTunes.

When developing SunFlower 0.8 I changed one of the custom views to use core animation. Faced with the choice to either hook up the new view to a standard cocoa scrollbar or create a custom core animation one I chose the latter, and completely plagiarized the scrollbar in iTunes. Many people use iTunes so this component provides a flashier scrollbar interface that is still familiar to users.
A scrollbar is made up of a couple of different parts and it is useful to define what those parts are called. You may find these defined differently elsewhere, however these are the terms that were chosen for the source.

The scroll arrows and the slider are drawn and then masks are applied to them to create the rounded effects. The image below shows the layer hierarchy used to create this component.

Because the slider can grow in size depending on the amount of content being shown it is broken up into three layers (left, middle and right). Masks are applied to the left and the right layers and their size remains constant, the middle layer grows as needed.
If you decide to use this code as a basis for an application, the first thing you most likely will want to do is to replace the content view. To make this as easy as possible I have defined protocols in the file SFScrollerProtocols.h
@protocol SFScrollerContentController - (BOOL)isRepositioning; - (void)scrollPositionChanged:(CGFloat)position; - (void)scrollContentResized; @end @protocol SFScrollerContent - (CGFloat)contentWidth; - (CGFloat)visibleWidth; - (CGFloat)stepSize; - (void)moveScrollView:(CGFloat)dx; // where position is a number between 0.0 and 1.0 representing the // posible positions the visible rect can be at - (void)scrollToPosition:(CGFloat)position; @end
Although the protocols aren’t documented very well, a little peeking and poking at the kode should get you what you want.
You can grab the kode here.
Using a mask on a core animation layer is quite easy but sample code is always good. So I’ve posted some sample code that does the following:
Voila!

You can grab the source here.