在保留角落的同时拉伸UIImage

时间:2012-01-16 12:09:24

标签: iphone ios4 ios5 uiimage drawing

我正在尝试拉伸导航箭头图像,同时保留边缘,以便中间伸展并且末端固定。

这是我试图伸展的图像:

enter image description here

以下iOS 5代码允许在调整大小时图像拉伸UIEdgeInsets定义的图像的中心部分。

[[UIImage imageNamed:@"arrow.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(15, 7, 15, 15)];

这会产生如下图像(如果图像的帧设置为70像素宽):

enter image description here

这实际上是我想要的,但只有iOS 5及更高版本才支持resizableImageWithCapInsets

在iOS 5之前,唯一类似的方法是stretchableImageWithLeftCapWidth:topCapHeight,但您只能指定顶部和左侧插图,这意味着图像必须具有相同的形状边缘。

是否有iOS 4方式调整图像大小与iOS 5的resizableImageWithCapInsets方法相同,或者采用其他方式?

5 个答案:

答案 0 :(得分:31)

你的假设是错误的:

  

在iOS 5之前,唯一类似的方法是stretchableImageWithLeftCapWidth:topCapHeight,但你只能指定顶部和左侧插图,这意味着图像必须具有相同的形状边缘。

帽子的计算方法如下 - 我将逐步穿过左帽,但同样的原则也适用于顶帽。

假设您的图片宽度为20px。

  • 左帽宽度 - 这是图像左侧无法拉伸的部分。在stretchableImage方法中,您为此发送的值为10。
  • 可伸缩部分 - 假设宽度为一个像素,因此想要更好的描述,它将是“11”列中的像素
  • 这意味着你图像的剩余9px有隐含的右上限 - 这也不会失真。

这取自documentation

  

leftCapWidth

     

端盖指定图像拉伸时不应调整大小的部分。该技术用于实现按钮和其他可调整大小的基于图像的界面元素。当调整带有端盖的按钮时,调整大小仅发生在按钮的中间,在端盖之间的区域中。端盖本身保持其原始尺寸和外观。

     

此属性指定左端盖的大小。假设中间(可伸展)部分是1个像素宽。因此,通过将左端盖和中间部分的尺寸相加,然后从图像的宽度中减去该值来计算右端盖:

     

rightCapWidth = image.size.width - (image.leftCapWidth + 1);

答案 1 :(得分:9)

UIImage *image = [UIImage imageNamed:@"img_loginButton.png"];
    UIEdgeInsets edgeInsets;
    edgeInsets.left = 0.0f;
    edgeInsets.top = 0.0f;
    edgeInsets.right = 5.0f; //Assume 5px will be the constant portion in your image
    edgeInsets.bottom = 0.0f;
    image = [image resizableImageWithCapInsets:edgeInsets];
//Use this image as your controls image

答案 2 :(得分:5)

使用stretchableImageWithLeftCapWidth:topCapHeight:左上角为15(显然,从阅读代码中)可以完全实现您的示例。这将通过重复中间列水平拉伸按钮。

答案 3 :(得分:4)

您可以扩展UIImage以允许使用自定义边缘保护来拉伸图像(从而拉伸图像内部,而不是平铺图像):

的UIImage + utils.h:

#import <UIKit/UIKit.h>
@interface UIImage(util_extensions)
//extract a portion of an UIImage instance 
-(UIImage *) cutout: (CGRect) coords;
//create a stretchable rendition of an UIImage instance, protecting edges as specified in cornerCaps
-(UIImage *) stretchImageWithCapInsets: (UIEdgeInsets) cornerCaps toSize: (CGSize) size;
@end

的UIImage + utils.m:

#import "UIImage+utils.h"
@implementation UIImage(util_extensions)
-(UIImage *) cutout: (CGRect) coords {
    UIGraphicsBeginImageContext(coords.size);
    [self drawAtPoint: CGPointMake(-coords.origin.x, -coords.origin.y)];
    UIImage *rslt = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return rslt;
}

-(UIImage *) stretchImageWithCapInsets: (UIEdgeInsets) cornerCaps toSize: (CGSize) size { 
    UIGraphicsBeginImageContext(size);

    [[self cutout: CGRectMake(0,0,cornerCaps.left,cornerCaps.top)] drawAtPoint: CGPointMake(0,0)]; //topleft
    [[self cutout: CGRectMake(self.size.width-cornerCaps.right,0,cornerCaps.right,cornerCaps.top)] drawAtPoint: CGPointMake(size.width-cornerCaps.right,0)]; //topright
    [[self cutout: CGRectMake(0,self.size.height-cornerCaps.bottom,cornerCaps.left,cornerCaps.bottom)] drawAtPoint: CGPointMake(0,size.height-cornerCaps.bottom)]; //bottomleft
    [[self cutout: CGRectMake(self.size.width-cornerCaps.right,self.size.height-cornerCaps.bottom,cornerCaps.right,cornerCaps.bottom)] drawAtPoint: CGPointMake(size.width-cornerCaps.right,size.height-cornerCaps.bottom)]; //bottomright

    [[self cutout: CGRectMake(cornerCaps.left,0,self.size.width-cornerCaps.left-cornerCaps.right,cornerCaps.top)]
 drawInRect: CGRectMake(cornerCaps.left,0,size.width-cornerCaps.left-cornerCaps.right,cornerCaps.top)]; //top

    [[self cutout: CGRectMake(0,cornerCaps.top,cornerCaps.left,self.size.height-cornerCaps.top-cornerCaps.bottom)]
 drawInRect: CGRectMake(0,cornerCaps.top,cornerCaps.left,size.height-cornerCaps.top-cornerCaps.bottom)]; //left

    [[self cutout: CGRectMake(cornerCaps.left,self.size.height-cornerCaps.bottom,self.size.width-cornerCaps.left-cornerCaps.right,cornerCaps.bottom)]
 drawInRect: CGRectMake(cornerCaps.left,size.height-cornerCaps.bottom,size.width-cornerCaps.left-cornerCaps.right,cornerCaps.bottom)]; //bottom

    [[self cutout: CGRectMake(self.size.width-cornerCaps.right,cornerCaps.top,cornerCaps.right,self.size.height-cornerCaps.top-cornerCaps.bottom)]
 drawInRect: CGRectMake(size.width-cornerCaps.right,cornerCaps.top,cornerCaps.right,size.height-cornerCaps.top-cornerCaps.bottom)]; //right

    [[self cutout: CGRectMake(cornerCaps.left,cornerCaps.top,self.size.width-cornerCaps.left-cornerCaps.right,self.size.height-cornerCaps.top-cornerCaps.bottom)]
 drawInRect: CGRectMake(cornerCaps.left,cornerCaps.top,size.width-cornerCaps.left-cornerCaps.right,size.height-cornerCaps.top-cornerCaps.bottom)]; //interior

    UIImage *rslt = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return [rslt resizableImageWithCapInsets: cornerCaps];
}

@end

答案 4 :(得分:2)

Swick 3.0版本的Vicky的答案。

var imageInset:UIEdgeInsets = UIEdgeInsets()
        imageInset.left = 10.0
        imageInset.top = 10.0
        imageInset.bottom = 10.0
        imageInset.right = 10.0
        self.myImageView.image = myimage.resizableImage(withCapInsets: imageInset)