Search code examples
ioscocoa-touchuibuttoncalayer

custom UIButton shadow


i have rounded rect UIButton and want to add shadow to it, but when i set the background image shadow is not visible, i think background overlays the shadow. without background image shadow is visible

customBtn=[UIButton buttonWithType:UIButtonTypeRoundedRect];
    customBtn.frame=CGRectMake(customBtn.frame.origin.x, customBtn.frame.origin.y, 30, 30);
     [customBtn setImage:[UIImage imageNamed:@"icon.png"] forState:UIControlStateNormal];
     [customBtn setBackgroundImage:[[UIImage imageNamed:@"bg.png"] stretchableImageWithLeftCapWidth:0 topCapHeight:0] forState:UIControlStateNormal];
    customBtn.layer.cornerRadius=9;

 customBtn.layer.shadowColor = [UIColor redColor].CGColor;
    customBtn.layer.shadowOpacity = 1.0;
    customBtn.layer.shadowRadius = 1;
    customBtn.layer.shadowOffset = CGSizeMake(2.0f, 2.0f);
customBtn.clipsToBounds=YES;

Solution

  • Due to the internal structure of UIButton, your best bet is to create a stretchable background image which includes the shadow.

    UIImage *bgWithShadow = [[UIImage imageNamed: @"bg.png"] 
                                stretchableImageWithLeftCapWidth: 10 
                                                    topCapHeight: 0];
    [customBtn setBackgroundImage: bgWithShadow 
                         forState: UIControlStateNormal];
    

    This example assumes that bg.png is a 21-pixels wide image which includes a shadow. Basically, you don't have to do anything else like accessing the button's layer or changing its clipsToBounds property. See this question to get an idea of what a stretchable image is (with pictures!).

    Note that stretchableImageWithLeftCapWidth:topCapHeight: is being deprecated in favor of resizableImageWithCapInsets:.