Yes there is.
The trick is to override -initWithCoder: and image settings ( setImage:forState: and setBackgroundImage:forState: to create resizable versions of the same image that you set to xib. Obviously, they still will not correctly resize in xib, but after initialization it will be resized correctly. Remember to set NAResizableButton as a custom UIButton class.
Of course, beats do this programmatically. :)
Interface:
Implementation:
#import "NAResizableButton.h" @implementation NAResizableButton - (id)initWithCoder:(NSCoder *)aDecoder { self = [super initWithCoder:aDecoder]; if (self) { [self setImage:[self imageForState:UIControlStateNormal] forState:UIControlStateNormal]; [self setImage:[self imageForState:UIControlStateHighlighted] forState:UIControlStateHighlighted]; [self setImage:[self imageForState:UIControlStateSelected] forState:UIControlStateSelected]; [self setImage:[self imageForState:UIControlStateDisabled] forState:UIControlStateDisabled]; [self setBackgroundImage:[self backgroundImageForState:UIControlStateNormal] forState:UIControlStateNormal]; [self setBackgroundImage:[self backgroundImageForState:UIControlStateHighlighted] forState:UIControlStateHighlighted]; [self setBackgroundImage:[self backgroundImageForState:UIControlStateSelected] forState:UIControlStateSelected]; [self setBackgroundImage:[self backgroundImageForState:UIControlStateDisabled] forState:UIControlStateDisabled]; } return self; } - (void)setImage:(UIImage *)inImage forState:(UIControlState)inState { UIEdgeInsets edgeInsets = UIEdgeInsetsMake(ceilf(inImage.size.height / 2), ceilf(inImage.size.width / 2), ceilf(inImage.size.height / 2), ceilf(inImage.size.width / 2)); if ([inImage respondsToSelector:@selector(resizableImageWithCapInsets:)]) { // iOS 5 inImage = [inImage resizableImageWithCapInsets:edgeInsets]; } else inImage = [inImage stretchableImageWithLeftCapWidth:edgeInsets.left topCapHeight:edgeInsets.top]; [super setImage:inImage forState:inState]; } - (void)setBackgroundImage:(UIImage *)inImage forState:(UIControlState)inState { UIEdgeInsets edgeInsets = UIEdgeInsetsMake(ceilf(inImage.size.height / 2), ceilf(inImage.size.width / 2), ceilf(inImage.size.height / 2), ceilf(inImage.size.width / 2)); if ([inImage respondsToSelector:@selector(resizableImageWithCapInsets:)]) { // iOS 5 inImage = [inImage resizableImageWithCapInsets:edgeInsets]; } else inImage = [inImage stretchableImageWithLeftCapWidth:edgeInsets.left topCapHeight:edgeInsets.top]; [super setBackgroundImage:inImage forState:inState]; } @end
source share