12

UIImage Method :

- (UIImage *)stretchableImageWithLeftCapWidth:(NSInteger)leftCapWidth topCapHeight:(NSInteger)topCapHeight.

Here the stretchable area is forced to be a single pixel high/wide.

I can not set the stretchable area, so I want to know: is there a UIImage category to do that?

After I googled, I found a lib.

Question: Is there a nine-patch loader for iPhone?

Announcement: http://blog.tortuga22.com/2010/05/31/announcing-tortuga-22-ninepatch/

https://i.stack.imgur.com/Rc6my.png

This is a source pic, and I want to stretch the inside gray rect.

Thanks in advance.

Community
  • 1
  • 1
guoxj
  • 198
  • 1
  • 1
  • 8
  • Why are you not using the nine-patch-loader-for-iphone – Manali Oct 25 '11 at 08:39
  • there may have a better solution,like a uiimage category,sth like this: - (UIImage *)imageWithStretchableRect:(CGRect)rect destRect:(CGRect)destRect – guoxj Oct 26 '11 at 05:08
  • i use this lib,and the affect is not what i want . i want to repeat some part of the image . – guoxj Oct 26 '11 at 08:17

5 Answers5

20

One way to achieve this is using the below approach,

UIImage * backgroundImg = [UIImage imageNamed:@"bg.png"];

backgroundImg = [backgroundImg resizableImageWithCapInsets:UIEdgeInsetsMake(2,2, 2, 2)];

[imgView setImage: backgroundImg];

UIEdgeInsetsMake(2,2, 2, 2) is the amount of pixels you want unstretchable.

Spidy
  • 1,137
  • 3
  • 28
  • 48
aToz
  • 2,463
  • 1
  • 24
  • 34
4

You can achieve nine patch with Tortuga22 software

You can find source from this GitHub here

Use it like this

[btnSubmit setImage: [TUNinePatchCache imageOfSize:[btnSubmit bounds].size 
                                forNinePatchNamed:@"imgNormalBackground"]
                       forControlState:UIControlStateNormal];
Azhar
  • 20,500
  • 38
  • 146
  • 211
2

As of iOS5, you can use resizableImageWithCapInsets: to achieve this.

jrturton
  • 118,105
  • 32
  • 252
  • 268
1

I didn't want to load so much code for the simple 9 patch images we had. So anyway, here's a simple solution to the problem for those interested. It's somewhat hard coded to our 3 pixel stretch regions but you could easily adjust those to your needs or find those in the image with some basic code and use that instead of my hard-coded inset parameters.

+ (UIImage *) makeNinePatchImage:(UIImage *)image;
{
    //Clear the black 9patch regions
    CGRect imageRect = CGRectMake(0.0, 0.0, image.size.width, image.size.height);
    UIGraphicsBeginImageContextWithOptions(image.size, NO, [UIScreen mainScreen].scale);
    [image drawInRect:imageRect];

    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextClearRect(context, CGRectMake(0, 0, image.size.width, 1));
    CGContextClearRect(context, CGRectMake(0, 0, 1, image.size.height));

    image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    UIEdgeInsets insets;

    //hard coded for now, could easily read the black regions if necessary
    insets.left = insets.right = image.size.width / 2 - 1;
    insets.top = insets.bottom = image.size.height / 2 - 1;

    UIImage *nineImage = [image resizableImageWithCapInsets:insets     
                          resizingMode:UIImageResizingModeStretch];

    return nineImage;

}

Then to use it in say, a button's background, just call it like this:

[self.dummyButton setBackgroundImage:[EVUtility makeNinePatchImage:learnMoreImage] forState:UIControlStateNormal];

Done.

Joel Teply
  • 3,260
  • 1
  • 31
  • 21
0

If I understand it right, you want the rectangle to grow in length and height. While there may be a more efficient solutions, what I could suggest is to break the boundary into a basic unit. Add this image repeatedly one next to the other to form the border rectangle of desired length and height. Then paint the inner rect with gray color.

Manali
  • 577
  • 4
  • 11
  • yes,exactly.i just want to repeat only part of image http://stackoverflow.com/questions/7901059/how-to-repeat-only-part-of-an-image thanks for you reply. your answer did help me – guoxj Oct 29 '11 at 02:08