2013-03-15 60 views
12

enter image description here如何拉伸UIImageView而不拉伸中心?

我想拉伸上面显示的图片的左侧和右侧,并保持中间的箭头未拉伸。我怎样才能做到这一点?

+0

您是否在不使用额外图像的情况下解决了此问题?如果是的话,请帮助我。 – 2015-06-11 07:29:05

回答

7

使用Photoshop或其他图像编辑工具将图像分成两部分:边缘和中心。边缘图像可以是一个像素宽,用于左边缘和右边缘;然而该中心很多像素宽度可以捕捉箭头。然后可以将三个UIImageView实例彼此相邻:左边缘,中心和右边缘。左右边缘被调整到所需的宽度,而中心保持其原始尺寸。

1

(没有太大的帮助,但在相反的支持:拉伸图像的中心和保持边缘部分相同的尺寸:见Stretching an UIImage while preserving the corners。)

煮了自己的解决方案,你可以可否创建一个包含三个部分的组件:左图像,中央图像,右图像。然后,通过确保中心部分保持相同宽度,同时左/右部分(图像)伸展,处理组件尺寸更改。

替代策略:创建一个组件,两个图像堆叠在一起。下面的图像是扁平条(无三角形),并水平延伸以填充可用空间。上面的图像是三角形的中心部分,并以可用空间为中心。这会产生你正在寻找的效果。

此外,还有一个应用程序(不是免费的!),可帮助您创建具有可伸缩性质的精美组件:PaintCode

+0

downvote的原因是什么? – occulus 2013-06-11 14:39:29

5

如果你不喜欢打扰Photoshop,如果图像没有动态调整大小,你可以在UIImage上使用我的分类方法。

名为“17maA.png”的示例图像为124像素宽。所以,你可以很容易地创建一个300像素宽的版本与此:

UIImage *image = [UIImage imageNamed:@"17maA"]; 
UIImage *newImage = [image pbResizedImageWithWidth:300 andTiledAreaFrom:10 to:20 andFrom:124-20 to:124-10]; 

这是类方法:

- (UIImage *)pbResizedImageWithWidth:(CGFloat)newWidth andTiledAreaFrom:(CGFloat)from1 to:(CGFloat)to1 andFrom:(CGFloat)from2 to:(CGFloat)to2 { 
    NSAssert(self.size.width < newWidth, @"Cannot scale NewWidth %f > self.size.width %f", newWidth, self.size.width); 

    CGFloat originalWidth = self.size.width; 
    CGFloat tiledAreaWidth = (newWidth - originalWidth)/2; 

    UIGraphicsBeginImageContextWithOptions(CGSizeMake(originalWidth + tiledAreaWidth, self.size.height), NO, self.scale); 

    UIImage *firstResizable = [self resizableImageWithCapInsets:UIEdgeInsetsMake(0, from1, 0, originalWidth - to1) resizingMode:UIImageResizingModeTile]; 
    [firstResizable drawInRect:CGRectMake(0, 0, originalWidth + tiledAreaWidth, self.size.height)]; 

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

    UIGraphicsBeginImageContextWithOptions(CGSizeMake(newWidth, self.size.height), NO, self.scale); 

    UIImage *secondResizable = [leftPart resizableImageWithCapInsets:UIEdgeInsetsMake(0, from2 + tiledAreaWidth, 0, originalWidth - to2) resizingMode:UIImageResizingModeTile]; 
    [secondResizable drawInRect:CGRectMake(0, 0, newWidth, self.size.height)]; 

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

    return fullImage; 
} 
+0

没有给出理由的投票是不好的... – Klaas 2013-06-13 19:55:05

+0

谢谢你。我做的一个小改变是圆形的tiledAreaWidth,就像这样:CGFloat tiledAreaWidth = ceil((newWidth - originalWidth)/2.0);否则,这可能会导致产生的图像出现细微的间隙。 – 2015-03-24 02:47:58

+0

只有大小增加在左侧而不是右侧。我怎样才能以相等的宽度(尺寸)拉伸两侧(左侧和右侧)? – 2015-06-11 07:53:53

-2

我们可以使用下面的代码图像伸展: - 在这里我们需要的箭头标记部分必须是相同的大小,所以我们舒展箭头开始下面的中间部分(假设它会在2 PX)

UIImage *image = [UIImage imageNamed:@"img_loginButton.png"]; 
    UIEdgeInsets edgeInsets; 
    edgeInsets.left = 0.0f; 
    edgeInsets.top = 2.0f; 
    edgeInsets.right = 0.0f; 
    edgeInsets.bottom = 0.0f; 
    image = [image resizableImageWithCapInsets:edgeInsets]; 
//Use this image as your controls image 
+0

该OP是想拉伸左侧和右侧,而不是顶部和底部。 – stevekohls 2013-06-11 13:11:01

+0

顶部/底部插图仅影响垂直拉伸。这不会以某种方式导致横向拉伸时箭头被忽略。如果你真的尝试了这个,当你水平调整大小时,箭头最终会被拉伸。 – 2014-08-08 00:22:04

1

Klaas的答案真的帮助编我,同样在雨燕3.0:

static func stretchImageSides(image: UIImage, newWidth: CGFloat) -> UIImage? { 
    guard image.size.width < newWidth else { 
     return image 
    } 

    let originalWidth = image.size.width 
    let tiledAreaWidth = ceil(newWidth - originalWidth)/2.0; 

    UIGraphicsBeginImageContextWithOptions(CGSize(width: originalWidth + tiledAreaWidth, height: image.size.height), 
              false, image.scale) 

    let firstResizable = image.resizableImage(withCapInsets: UIEdgeInsets(top: 0, 
                      left: 0, 
                      bottom: 0, 
                      right: originalWidth - 3), 
               resizingMode: .stretch) 
    firstResizable.draw(in: CGRect(x: 0, y: 0, width: originalWidth + tiledAreaWidth, height: image.size.height)) 

    let leftPart = UIGraphicsGetImageFromCurrentImageContext() 
    UIGraphicsEndImageContext() 

    UIGraphicsBeginImageContextWithOptions(CGSize(width: newWidth, height: image.size.height), 
              false, image.scale) 

    let secondResizable = leftPart?.resizableImage(withCapInsets: UIEdgeInsets(top: 0, 
                       left: tiledAreaWidth + originalWidth - 3, 
                       bottom: 0, 
                       right: 0), 
               resizingMode: .stretch) 
    secondResizable?.draw(in: CGRect(x: 0, y: 0, width: newWidth, height: image.size.height)) 

    let fullImage = UIGraphicsGetImageFromCurrentImageContext() 
    UIGraphicsEndImageContext() 

    return fullImage 
} 
  • 你只需要提供的图像,与期望的新宽度,它会做横向拉伸为您服务。