This blog has moved

April 22nd, 2008

This blog has moved to the following address:

http://sunflower.coleharbour.ca/cocoamondo/

Creating an iTunes Scrollbar

March 25th, 2008

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.

CAScrollBar

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.

The anatomy of our scrollbar

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.

scrollbarAnatomy

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.

Scroller Layers

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.

Protocols

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.

Core Animation: Using Layer Masks

March 17th, 2008

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:

  • Creates an NSImage by filling an NSBezierPath.
  • Converts the NSImage into a CGImageRef
  • Creates three CALayers
    • one to show what the mask looks like
    • one for the layer that will have
    • one for our our mask

Voila!

calayermask.png

You can grab the source here.