Awesome
<img src="https://raw.github.com/hoteltonight/HTDelegateProxy/master/ht-logo-black.png" alt="HotelTonight" title="HotelTonight" style="display:block; margin: 10px auto 30px auto;">HTRasterView
Overview
HTRasterView is a rasterization system that caches rendered components based on state. A few advantages over Core Animation's rasterization:
- You only draw a component once for each unique state
- Asynchronous drawing is supported for non-nested use cases
- Intelligent cached component nesting
- Components that support edge capping (resizable UIImage) render in their smallest possible frame (performance gain)
- 'Precompute' GPU-intensive operations like alpha compositing and masking into a single image
- Switch manually between rasterized version and actual component
Check out the associated blog post at http://engineering.hoteltonight.com/asynchronous-state-aware-component-rasterizat
Installation
This library is dependent on the MSCachedAsyncViewDrawing class by Javier Soto of MindSnacks. The recommended installation method is cocoapods, which handles this dependency automatically. Add this line to your Podfile:
pod 'HTRasterView'
Usage
Start by conforming to the HTRasterizableView protocol. A simple example is provided in the demo project (HTExampleRasterizableComponent). The single required method is:
- (NSArray *)keyPathsThatAffectState;
This is used for two purposes: <br/>
- To key-value observe the specified key paths to trigger image regeneration <br/>
- To generate a hash of the component's state
Initialize a HTStateAwareRasterImageView and set the rasterizableView property to your HTRasterizableView, like this snippet from the demo project:
_rasterizableComponent = [[HTExampleRasterizableComponent alloc] init];
_rasterView = [[HTRasterView alloc] init];
_rasterView.rasterizableView = _rasterizableComponent;
_rasterView.delegate = self;
[self addSubview:_rasterView];
If your component can take advantage of UIImage caps (fixed-size corners and stretchable center), these two methods are optional on the HTRasterizableView protocol: <br/>
- (UIEdgeInsets)capEdgeInsets;
- (BOOL)useMinimumFrameForCaps;
You can specify if you want drawing to occur synchronously on the main thread (async doesn't work with nesting):
@property (nonatomic, assign) BOOL drawsOnMainThread;
You can also turn off keypath observing if you want to manually regenerate images (use this for pre-rendering assets):
@property (nonatomic, assign) BOOL kvoEnabled;
// For prerendering only
- (void)regenerateImage:(HTSARIVVoidBlock)complete;
A delegate property is also available to let you know when it's regenerating an image, and when it gets a new image back:
@property (atomic, assign) id<HTStateAwareRasterImageViewDelegate> delegate;
For debugging purposes, the cache key is available through this method.
- (NSString *)cacheKey;
Demo project
The demo project has four tabs:
- A tableview taking advantage of HTRasterView
- A tableview that displays cache key, actual size and cell-height sized cached images
- A tableview that uses the same component without rasterization
- A tableview that uses the same component with Core Animation rasterization enabled
Limitations
Hashing
The cache key used to define the state of your component is generated by the NSObject+HTPropertyHash category. It is important that the hash method produces a string that is unique to the state of your properties, but not TOO unique by including things like pointer values. The exception for CGColorRef in that category is made because we only want the RGBA values described, not the pointer value plus the RGBA values.
Use it? Love/hate it?
Tweet the author @jakejennings, and check out HotelTonight's engineering blog: http://engineering.hoteltonight.com
Also, check out HotelTonight's other iOS open source: