`
啸笑天
  • 浏览: 3465571 次
  • 性别: Icon_minigender_1
  • 来自: China
社区版块
存档分类
最新评论

类似9patch效果的iOS图片拉伸

 
阅读更多

下面张图片,本来是设计来做按钮背景的:


  button.png,尺寸为:24x60

现在我们把它用作为按钮背景,按钮尺寸是150x50:

// 得到view的尺寸
CGSize viewSize = self.view.bounds.size;

// 初始化按钮
UIButton *button = [[UIButton alloc] init];
// 设置尺寸
button.bounds = CGRectMake(0, 0, 150, 50);
// 设置位置
button.center = CGPointMake(viewSize.width * 0.5f, viewSize.height * 0.5f);

// 加载图片
UIImage *image = [UIImage imageNamed:@"button"];
// 设置背景图片
[button setBackgroundImage:image forState:UIControlStateNormal];

// 添加按钮
[self.view addSubview:button];

 

运行效果图:



 

可以看到,效果非常地差。原因很简单,因为原图大小为24x60,现在整张图片被全方位拉伸为150x50,比较严重的是图片的4个角。

有些人可能马上想到一个解决方案,你叫美工把图片做大一点不就好了么,怎么拉伸都没事。没错,这是一种解决方案,不过不建议采取。原因很简单:1.图片大,导致安装包也大,加载到内存中也大;2.有更好的解决方案。

细看一下图片,其实图片会变得难看,完全是因为4个角被拉伸了,中间的拉伸并没有明显地丑化外观。因此要想小图片被拉伸后不会变得难看,在图片拉伸的时候,我们只需拉伸图片的中间一块矩形区域即可,不要拉伸边缘部分。

比如只拉伸下图的矩形区域,上下左右的边缘都不拉伸:



 

iOS中提供很好用的API帮我们实现上述功能。到iOS 6.0为止,iOS提供了3种图片拉伸的解决方案,接下来分别详细介绍这些方案。

一、iOS 5.0之前

iOS中有个叫端盖(end cap)的概念,用来指定图片中的哪一部分不用拉伸。比如下图中,黑色代表需要被拉伸的矩形区域,上下左右不需要被拉伸的边缘就称为端盖。



 

使用UIImage的这个方法,可以通过设置端盖宽度返回一个经过拉伸处理的UIImage对象

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

 

这个方法只有2个参数,leftCapWidth代表左端盖宽度,topCapHeight代表顶端盖高度。系统会自动计算出右端盖宽度(rightCapWidth)和底端盖高度(bottomCapHeight),算法如下:

// width为图片宽度
rightCapWidth = width - leftCapWidth - 1;

// height为图片高度
bottomCapHeight = height - topCapHeight - 1

 

经过计算,你会发现中间的可拉伸区域只有1x1

// stretchWidth为中间可拉伸区域的宽度
stretchWidth = width - leftCapWidth - rightCapWidth = 1;
    
// stretchHeight为中间可拉伸区域的高度
stretchHeight = height - topCapHeight - bottomCapHeight = 1;

 

因此,使用这个方法只会拉伸图片中间1x1的区域,并不会影响到边缘和角落。

下面演示下方法的使用:

// 左端盖宽度
NSInteger leftCapWidth = image.size.width * 0.5f;
// 顶端盖高度
NSInteger topCapHeight = image.size.height * 0.5f;
// 重新赋值
image = [image stretchableImageWithLeftCapWidth:leftCapWidth topCapHeight:topCapHeight];

 

调用这个方法后,原来的image并不会发生改变,会产生一个新的经过拉伸的UIImage,所以第6行中需要将返回值赋值回给image变量

运行效果:




 可以发现,图片非常美观地显示出来了

注意:

1.这个方法在iOS 5.0出来后就过期了

2.这个方法只能拉伸1x1的区域

 

二、iOS 5.0

在iOS 5.0中,UIImage又有一个新方法可以处理图片的拉伸问题

- (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets

 

这个方法只接收一个UIEdgeInsets类型的参数,可以通过设置UIEdgeInsets的left、right、top、bottom来分别指定左端盖宽度、右端盖宽度、顶端盖高度、底端盖高度

CGFloat top = 25; // 顶端盖高度
CGFloat bottom = 25 ; // 底端盖高度
CGFloat left = 10; // 左端盖宽度
CGFloat right = 10; // 右端盖宽度
UIEdgeInsets insets = UIEdgeInsetsMake(top, left, bottom, right);
// 伸缩后重新赋值
image = [image resizableImageWithCapInsets:insets];

 

运行效果:




 
 

 

三、iOS 6.0

在iOS6.0中,UIImage又提供了一个方法处理图片拉伸

 

- (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets resizingMode:(UIImageResizingMode)resizingMode

 

对比iOS5.0中的方法,只多了一个UIImageResizingMode参数,用来指定拉伸的模式:

  • UIImageResizingModeStretch:拉伸模式,通过拉伸UIEdgeInsets指定的矩形区域来填充图片
  • UIImageResizingModeTile:平铺模式,通过重复显示UIEdgeInsets指定的矩形区域来填充图片
CGFloat top = 25; // 顶端盖高度
CGFloat bottom = 25 ; // 底端盖高度
CGFloat left = 10; // 左端盖宽度
CGFloat right = 10; // 右端盖宽度
UIEdgeInsets insets = UIEdgeInsetsMake(top, left, bottom, right);
// 指定为拉伸模式,伸缩后重新赋值
image = [image resizableImageWithCapInsets:insets resizingMode:UIImageResizingModeStretch];

运行效果:



 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 大小: 5.7 KB
  • 大小: 9.2 KB
  • 大小: 6.9 KB
  • 大小: 48.4 KB
  • 大小: 7.5 KB
  • 大小: 7.5 KB
  • 大小: 7.5 KB
分享到:
评论
3 楼 xnwuxin 2014-11-23  
谢谢......
2 楼 啸笑天 2013-12-09  
//
//  UIImage+EASY.m
//  BTN2GO2013
//
//  Created by NeuLion SH on 13-12-9.
//  Copyright (c) 2013年 cactus. All rights reserved.
//

#import "UIImage+EASY.h"

@implementation UIImage (EASY)
-(UIImage *) resizableImageWithCapInsets2: (UIEdgeInsets) inset
{
    if ([self respondsToSelector:@selector(resizableImageWithCapInsets:resizingMode:)])
    {
        return [self resizableImageWithCapInsets:inset resizingMode:UIImageResizingModeStretch];
    }
    else
    {
        float left = (self.size.width-2)/2;//The middle points rarely vary anyway
        float top = (self.size.height-2)/2;
        return [self stretchableImageWithLeftCapWidth:left topCapHeight:top];
    }
}
@end
1 楼 啸笑天 2013-11-09  
在Interface Builder中,UIButton的backgroundImage不支持拉伸,准确的说是UIButton中的backgroundImage不能支持contentStretch属性,在IB中,不能单独对UIButton的backgroundImage设置contentStretch属性。这个属性可以在代码中设置,如下:
UIImage *backgroundImage = [[UIImage imageNamed:@"ImageBackground.png"] stretchableImageWithLeftCapWidth:10 topCapHeight:0];
[myButton setBackgroundImage:backgroundImage forState:UIControlStateNormal];

相关推荐

    iOS实现图片边缘拉伸.zip

    通过这个代码类别,开发者可以轻松地在iOS应用中实现自定义的图片拉伸效果,使得图片能够适应各种屏幕尺寸和布局变化,提高了用户体验。不过,使用前需要理解代码的工作原理,以及如何正确地应用9-patch图像格式,...

    [ios]实现图片部分拉伸(与android9图类似)

    在iOS开发中,有时我们需要对图片进行特定区域的拉伸,以适应不同尺寸的界面,这与Android中的9-patch图概念相似。9-patch图在Android中是一种可伸缩的图片格式,允许开发者指定图像的拉伸区域,确保图片在放大时...

    .9.png图片,用android自带的 工具制作完,图片四周有黑线,可以使用这个工具去掉黑线

    然而,在使用Android自带的绘图工具(如Draw9Patch)创建或编辑`.9.png`图片时,有时会出现图片四周有黑线的问题。这些黑线可能会影响界面的美观和整体设计的一致性。 首先,我们需要理解为什么会出现黑线。黑线...

    Android高级应用源码-仿IOS的圆角设置界面。直接可用,单选多选等ATable_Demo(iOS风格设置).rar

    4. **Nine-Patch图片**: 对于需要拉伸的背景图,开发者可能会使用Nine-Patch图片,这种图片格式允许指定可拉伸区域和不变形区域,同时可以设定圆角。 5. **渲染阴影效果**: iOS界面往往有明显的阴影效果,Android中...

    Android 图片阴影效果和影子效果.zip

    这通常涉及到使用第三方库,如`Android-Image-Blur`,先模糊背景,再将其叠加到前景元素上,以实现类似iOS中的毛玻璃效果。 以上是Android图片阴影和影子效果的一些实现方式,通过这些技术,开发者可以提升应用的...

    Android磨砂效果

    9-patch图片允许你指定图像的拉伸区域,这样即使在不同尺寸的屏幕上,磨砂效果也能保持一致。 6. **利用硬件加速**: 在实现磨砂效果时,应确保你的应用启用了硬件加速,因为这可以极大地提高图像处理的速度。在...

    android常用图片特效处理.zip

    9. 高斯模糊:通过渲染脚本或者第三方库,可以在Android上实现类似iOS的模糊效果,用于背景或半透明视图。 10. 自定义View:对于更复杂的图片特效,可能需要自定义View或Drawable来实现。例如,创建一个可拖动的...

    Android实现iphone圆角ListView和点击的效果

    在Android开发中,为了使应用界面更接近iOS的风格或者增加独特的用户体验,有时我们需要实现类似iPhone的圆角ListView以及点击效果。本篇文章将详细讲解如何在Android中复现这一功能。 首先,我们要创建一个带有...

    Android源码——仿iPhoneQQ气泡聊天样式源码.zip

    8. 资源优化:优化图像资源,使用9-patch图片(.9.png)来处理气泡的拉伸部分,确保在不同尺寸的屏幕上都能正确显示。 9. 多样化设计:源码可能包含了不同的气泡样式,如发送和接收消息的气泡颜色和箭头方向的差异...

    Android多分辨率多密度下UI适配方案

    9-patch是一种特殊的PNG图片格式,可以指定图像的拉伸区域,使得图片在不同尺寸下仍能保持正确的比例和内容填充。这对于按钮、背景图等需要自适应大小的元素非常有用。 4. Vector Drawable: 为了进一步优化资源...

Global site tag (gtag.js) - Google Analytics