Skip to content

Subclassing EKSwipeControl

ChrisSchneider edited this page Jun 14, 2012 · 21 revisions

In order to subclass the EKSwipeControl class you should import the EKSwipeControl_Subclass.h header.

#import "EKSwipeControl_Subclass.h"

Methods to Overwrite

  • By overwriting the initializeVariables and initializeViews methods the initialization of the control can be simplified.
  • configureAppearance is used to update the appearance of the control.
  • overlayRectForBounds: can be overwritten to change the position and size of the overlay.

initializeVariables

- (void)initializeVariables;

This method is called by the init and initWithFrame: and initWithCoder methods.

Example

- (void)initializeVariables
{
    [super initializeVariables];
    
    // Initialize variables here!
}

initializeViews

- (void)initializeViews;

This method is called by the init and initWithFrame: and awakeFromNib methods.
The views should only be initialized if they are set to nil!

Example

- (void)initializeViews
{
    [super initializeViews];

    if (_mySubview == nil) {
        _mySubview = [ [UIView alloc] init];
        // ...
    }
}

configureAppearance

- (void)configureAppearance;

You should overwrite this method to update the "state-specific" appearance of the control.
This method is called when the state of the control changes, the overlayColor changes et cetera...

- (void)configureAppearance
{
    [super configureAppearance];
    
    self.trackView.backgroundColor = self.currentTrackColor;
}

overlayRectForBounds:

- (CGRect)overlayRectForBounds:(CGRect)bounds;

Overwrite this method to change the position and size (frame) of the overlay.

Example

- (CGRect)overlayRectForBounds:(CGRect)bounds
{
    CGRect rect = [super overlayRectForBounds:bounds];
    
    // Customization...
        
    return rect;
}

Appearance

Implementing propertyForState: and setProperty:forState:

This property stores values for different states.

Example

First, add a dictionary containing the state-value-combination to the ivars.

{
    @private
    NSMutableDictionary *_propertyDict;
}

Then implement the getter and setter methods:

- (id)propertyForState:(UIControlState)state
{
    return [_propertyDict objectForKey:[NSNumber numberWithUnsignedInteger:state]];
}

- (void)setProperty:(id)value forState:(UIControlState)state
{
    NSNumber *key = [NSNumber numberWithUnsignedInteger:state];
    
    if (value != [_propertyDict objectForKey:key]) {
        [_propertyDict setObject:value forKey:key];
    
        // Update the appearance
        [self configureAppearanceAnimated:NO];
    }
}

Implementing currentProperty

This property is used to retrieve the value for the current state using values retrieved via the propertyForState: method and appearance proxy. For additional documentation scroll down for infos on the findAppearanceValueWithBlock: utility method!

Example Implementation

- (UIColor *)currentTrackColor
{
    UIColor *color = [self findAppearanceValueWithBlock:^id(UIControlState state) {

        // First try to get the color from _this_ object...
        UIColor *color = [self trackColorForState:state];
    
        // ... then try to get the color from the appearance proxy
        if (color == nil) {
            color = [self.class.appearance trackColorForState:state];
        }
    
        return color;
    }];

    // Fallback
    if (color == nil) {
        color = [UIColor colorWithWhite:0.4f alpha:0.5f];
    }

    return color;
}

Appearance Utility Methods

configureAppearanceAnimated:

- (void)configureAppearanceAnimated:(BOOL)animated;

This method calls configureAppearance to update the appearance of the control.

findAppearanceValueWithBlock:

typedef id(^EKSwipeControlAppearanceValueBlock)(UIControlState state);

- (id)findAppearanceValueWithBlock:(EKSwipeControlAppearanceValueBlock)block;

The method tries to obtain the value by calling the block with the following states until a non-nil value is returned:

  1. current state
  2. EKSwipeControlOverlayFadedState
    if the EKSwipeControlOverlayFadedState flag is set
  3. EKSwipeControlOverlayVisibleState
    if the EKSwipeControlOverlayVisibleState flag is set
  4. UIControlStateNormal

Example

    id value = [self findAppearanceValueWithBlock:^id(UIControlState state) {
        id value = [self propertyForState:state];
    
        if (value == nil) {
            value = [self.class.appearance propertyForState:state];
        }
    
        return value;
    }];

Tracking Utility Methods

isPan

- (BOOL)isPan;

Returns weather a pan has be detected.

initialTouchLocation

- (CGPoint)initialTouchLocation;

Returns the initial touch location.