Stretch background image for UIButton
Asked Answered
C

5

34

I got texture, which really shorter, than my UIButton.

I got this texture:

enter image description here

And i should create this button:

enter image description here

How should i stretch (not tile), this texture? Stretching in horizontal direction

Thnx

Cotangent answered 27/9, 2012 at 14:39 Comment(0)
D
69

From the example images you provided I'm pretty sure you're looking for UIImage's resizableImageWithCapInsets:

UIImage *originalImage = [UIImage imageNamed:@"myImage.png"];
UIEdgeInsets insets = UIEdgeInsetsMake(top, left, bottom, right);
UIImage *stretchableImage = [originalImage resizableImageWithCapInsets:insets];
[myButton setBackgroundImage:stretchableImage forState:UIControlStateNormal];
// the image will be stretched to fill the button, if you resize it.

The values in the UIEdgeInsets struct determine the margins you don't want to be stretched. Your left and right values could be about this wide:

enter image description here

The top and bottom values can be either 0 (if you don't want to resize the button vertically), or probably half of the total height.

Dimmick answered 27/9, 2012 at 15:38 Comment(5)
resizableImageWithCapInsets available in iOS 5.0 and later. do you know somethinf for iOS 4.3?Cotangent
Probably not the answer you wanted, but the last estimate I saw was that 90% of all iPhones are running at least iOS 5.0. iOS6 already had 30% penetration after 8 days. Just sayin', you might consider changing your target rather than trying to shoe-horn a solution into 4.3.Priority
@drummerb You should be using setBackgroundImage:forState instead of setImage:forState.Priority
Here's a little tool I wrote that might help: cocoacontrols.com/controls/thecapperPasserine
This created some of the strangest behaviors I've ever seen.Consignee
D
38

With Xcode 6 (and iOS7+ target) you can use slicing editor when working with images assets. Toggle slicing mode with Editor -> Show Slicing menu or press Show Slicing button when select specific image with editor (showed below).

Show Slicing button

Then you can select image for specific display scale and drag rules or edit insets values manually.

Rules

After that you can select this image in Interface Builder for UIButton Background Image (IB button's representation could look bad, but it should be OK when running).

My buttons look well (running iOS 7.1 simulator and iOS 8 device).

enter image description here

This Apple doc link could be helpful.

Dosi answered 2/3, 2015 at 8:27 Comment(3)
Just curious, even after slicing you still need to set the content insets of your UIButton right?Sopher
@DanielGalasko no need to set the content inset. For me just slicing did the job.Eury
Don't get fooled by interface builder! It works with running app.Genista
L
3

By not tiling, I assume you can thus not use

- (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets

The way to do what you want is to use:

UIGraphicsBeginImageContextWithOptions(newSize, NO, 0); // should be proportionally larger
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextDrawImage(context, (CGRect){{0,0}, newSize}, [yourImage CGImage]);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
Lilytrotter answered 27/9, 2012 at 14:49 Comment(1)
Well, you sort of changed your question after I responded, so @Dimmick provided the answer I would have given you, but then he gave you a really nice image of how to define the caps! I just gave him a +1 primarily for the image that shows you exactly how to do it!Lilytrotter
P
1

Use stretchableImageWithLeftCapWidth:topCapHeight: method.

Refer: https://github.com/boctor/idev-recipes/tree/master/StretchableImages

Poche answered 1/2, 2013 at 21:31 Comment(1)
deprecated for resizableImageWithCapInsets:Cornie
S
1

Or using Stretchable Images:

UIImage* imgbkg =[[UIImage imageNamed: @"my_bkg_image.png"] stretchableImageWithLeftCapWidth:10 topCapHeight:10];

[_button setBackgroundImage: imgbkg forState: UIControlStateNormal];

Use 0 if you don't want to stretch certain side.

Seducer answered 7/4, 2015 at 22:49 Comment(3)
deprecated for resizableImageWithCapInsets:Cornie
@Cœur is it really deprecated? I always use this because it is simpler.Seducer
deprecated since iOS5. But if you still support iOS4, the old way is still supported even with iOS9.Cornie

© 2022 - 2024 — McMap. All rights reserved.