Francis F
Francis F

Reputation: 3285

How to set background for UIButtons with dynamic width?

I have 3 button images named edit_category_left_up,edit_category_middle_up and edit_category_right_up enter image description here enter image description here enter image description here

I have written code to create buttons with dynamic width now I need to set background of these button like this image below using the above 3 images

enter image description here

This is my current code to create dynamic buttons

-(void) addDynamicButtonsForCategories
{
    _adcImage.hidden=YES;
    _makeADCLabel.hidden=YES;

    float x=0; float y=0; float frameHeight=_subADCView.frame.size.height;
    NSString *titleString=@"";
    for(int i = 0; i < 15; i++)
    {
      UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];

        if (i<1)
        {
            [btn setFrame:CGRectMake(0, 0, 39, 39)];
            [btn setImage:[UIImage imageNamed:@"addcategory_up.png"] forState:UIControlStateNormal];
            [btn setImage:[UIImage imageNamed:@"addcategory_down.png"] forState:UIControlStateHighlighted];

            x = x + btn.frame.size.width+10; y=y+btn.frame.origin.y;
            [btn setTitle:titleString forState: UIControlStateNormal];

            [btn setTag:i];

        }
       else
       {
        titleString = [titleString stringByAppendingString:[NSString stringWithFormat:@"%d",i]]; // get button title

        CGSize fontSize = [titleString sizeWithFont:[UIFont systemFontOfSize:12.0]];
        CGRect currentFrame = btn.frame;

        CGRect buttonFrame = CGRectMake(x, y, fontSize.width + 22.0, 40);

        if ((buttonFrame.origin.x+buttonFrame.size.width) >_subADCView.frame.size.width)
        {
            x=0;y=_subADCView.frame.size.height;

            _subADCView.frame=CGRectMake(_subADCView.frame.origin.x, _subADCView.frame.origin.y, _subADCView.frame.size.width, _subADCView.frame.size.height+frameHeight);
             buttonFrame = CGRectMake(x, y, fontSize.width+ 22.0, 40);

        }

        x = x + fontSize.width + 35.0; y=y+currentFrame.origin.y;
        [btn setFrame:buttonFrame];

//I need to set the button image here
      [btn setImage:[[UIImage imageNamed:@"edit_category_middle_up.png"] stretchableImageWithLeftCapWidth:10 topCapHeight:0] forState:UIControlStateNormal];
      [btn setImage:[[UIImage imageNamed:@"edit_category_middle_down.png"] stretchableImageWithLeftCapWidth:10 topCapHeight:0] forState:UIControlStateHighlighted];

            [btn setTitle:titleString forState: UIControlStateNormal];

            [btn setTag:i];
            lastButtonPosition=btn.frame.origin.y+btn.frame.size.height;
           }
            [self.subADCView addSubview:btn];

        }
         [self readjustSubviews];
    }

Upvotes: 3

Views: 1041

Answers (4)

Raon
Raon

Reputation: 1286

Try this code to combine three images

-(UIImage*)combineImages
{
    UIImage *image1 = [UIImage imageNamed:@"test.png"];
    UIImage *image2 = [UIImage imageNamed:@"yyu.png"];
    UIImage *image3=[UIImage imageNamed:@"test.png"];
    //self.imageView.image=image3;
    CGSize size = CGSizeMake(image1.size.width+image2.size.width+image3.size.width, image1.size.height );

    UIGraphicsBeginImageContext(size);

    [image1 drawInRect:CGRectMake(0,0,image1.size.width, size.height)];
    [image2 drawInRect:CGRectMake(image1.size.width,0,image2.size.width, size.height)];
    [image3 drawInRect:CGRectMake(image1.size.width+image2.size.width, 0,image3.size.width,size.height)];

    UIImage *finalImage =UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return finalImage;

}

Upvotes: 0

iDevAmit
iDevAmit

Reputation: 1578

Just look into this thread once. May be this is not for what you are looking, but I hope it may be helpful for you or someone else.

Build a UIImage with multiple stretchable images

Upvotes: 0

Fogmeister
Fogmeister

Reputation: 77631

Are you writing for iOS7 only?

If so make a single "stretchable" image and import it into the project using an Asset Catalog.

From here you can then specify the properties of the stretchable image (i.e. cap insets etc...) in the catalog.

Then to set the background image correctly you just use...

[button setBackgroundImage:[UIImage imageNamed:@"BackgroundImage"] forState:UIControlStateNormal];

This will take the resizable/stretchable properties from the asset catalog.

Upvotes: 0

null0pointer
null0pointer

Reputation: 1543

You only need the background in a single image if you use the following technique.

UIImage *backgroundImage = [[UIImage imageNamed:@"MyImageTitle"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, leftInset, 0, rightInset)];

where leftInset is the width of unstretchable content from the left side of the image and rightInset is the width of unstretchable content from the right side of the image.

This will create an image that only stretches content inside the defined insets. This is the best way to solve this problem.

Alternatively, if you cannot possibly combine your images then you can do it like this.

UIImage *leftImage = [UIImage imageNamed:@"edit_category_left_up"];
UIImage *middleImage = [UIImage imageNamed:@"edit_category_middle_up"];
UIImage *rightImage = [UIImage imageNamed:@"edit_category_right_up"];

UIImageView *leftImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, leftImage.size.width, btn.frame.size.height)];
[leftImageView setImage:leftImage];

UIImageView *middleImageView = [[UIImageView alloc] initWithFrame:CGRectMake(leftImageView.frame.size.width, 0, btn.frame.size.width - (leftImage.size.width + rightImage.size.width), btn.frame.size.height)];
[middleImageView setImage:middleImage];

UIImageView *rightImageView = [[UIImageView alloc] initWithFrame:CGRectMake(middleImageView.frame.origin.x + middleImageView.frame.size.width, 0, rightImage.size.width, btn.frame.size.height)];
[rightImageView setImage:rightImage];

[btn addSubview:leftImageView];
[btn addSubview:middleImageView];
[btn addSubview:rightImageView];

You might need to play around with the layer the subviews are inserted at. To do that you can use one of these methods:

[btn insertSubview:view aboveSubview:otherView];

[btn insertSubview:view atIndex:someIndex];

[btn insertSubview:view belowSubview:otherView];

Upvotes: 1

Related Questions