Thursday, May 30, 2013

UIButton backgroundRectForBounds example in Objective C (iOS).

UIButton backgroundRectForBounds

Returns the rectangle in which the receiver draws its background.

- (CGRect)backgroundRectForBounds:(CGRect)bounds

Parameters
bounds
The bounding rectangle of the receiver.

Return Value
The bounds rectangle in which to draw any standard button content.

Discussion of [UIButton backgroundRectForBounds]
The default implementation of this method returns the value in the bounds parameter. This rectangle represents the area in which the button draws its standard background content. Subclasses that provide custom background adornments can override this method and return a modified bounds rectangle to prevent the button from drawing over any custom content.

UIButton backgroundRectForBounds example.
@interface StretchableXButton : UIButton
{
    CGFloat imageHeight;
}
@property CGFloat imageHeight;  // we need this later when we override an instance method

+ (id)buttonWithFrame:(CGRect)frame;

@end
@implementation StretchableXButton
@synthesize imageHeight;

+ (id)buttonWithFrame:(CGRect)frame
{
    StretchableXButton *button = [super buttonWithType:UIButtonTypeCustom];

    UIImage *normalImage = [UIImage imageNamed: @"ButtonBGNormal.png" ];
    UIImage *highlightedImage = [UIImage imageNamed:@"ButtonBGHighlighted.png" ];

    button.frame = frame;
    button.imageHeight = normalImage.size.height;  // we need him later in the method below

    // make the images stretchable
    normalImage = [normalImage stretchableImageWithLeftCapWidth:normalImage.size.width/2 topCapHeight:normalImage.size.height/2];
    highlightedImage = [highlightedImage stretchableImageWithLeftCapWidth:normalImage.size.width/2 topCapHeight:normalImage.size.height/2];

    button.backgroundColor = [UIColor clearColor];

    // SET OTHER BUTTON PROPERTIES HERE (textLabel, fonts, etc.)

    [button setBackgroundImage:normalImage forState:UIControlStateNormal];
    [button setBackgroundImage:highlightedImage forState:UIControlStateHighlighted];

    return  button;
}

// THIS IS THE TRICK.  We make the height of the background rect match the image.
-(CGRect)backgroundRectForBounds:(CGRect)bounds
{
    CGRect bgRect = bounds;
    bgRect.origin.y = (bounds.size.height - imageHeight)/2.0f;
    bgRect.size.height = imageHeight;

    return bgRect;
}
@end

Example of [UIButton backgroundRectForBounds].
- (CGRect)backgroundRectForBounds:(CGRect)bounds {
    CGRect result = [super backgroundRectForBounds:bounds];
    if (self.highlighted)
        result = CGRectInset(result, -3, -3);
    return result;
}

UIButton backgroundRectForBounds example.
WJBackgroundInsetButton.h

#import 

@interface WJBackgroundInsetButton : UIButton {
    UIEdgeInsets backgroundEdgeInsets_;
}

@property (nonatomic) UIEdgeInsets backgroundEdgeInsets;

@end
WJBackgroundInsetButton.m

#import "WJBackgroundInsetButton.h"

@implementation WJBackgroundInsetButton

@synthesize backgroundEdgeInsets = backgroundEdgeInsets_;

-(CGRect) backgroundRectForBounds:(CGRect)bounds {
    CGRect sup = [super backgroundRectForBounds:bounds];
    UIEdgeInsets insets = self.backgroundEdgeInsets;
    CGRect r = UIEdgeInsetsInsetRect(sup, insets);
    return r;
}

@end

End of UIButton backgroundRectForBounds example article.