假如下面的一张图片,是用来做按钮的背景图片的,原始尺寸是(128 * 112
)
我们通过代码将这张图片设置为按钮的背景图片,假如我们将创建好的按钮的宽高设置为:(W=200, H=50
)代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 #import "ViewController.h" @interface ViewController ()@end @implementation ViewController - (void )viewDidLoad { [super viewDidLoad]; UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom ]; btn.frame = CGRectMake (100 , 300 , 200 , 50 ); UIImage *image = [UIImage imageNamed:@"chat_send_nor" ]; [btn setBackgroundImage:image forState:UIControlStateNormal ]; [self .view addSubview:btn]; } - (void )didReceiveMemoryWarning { [super didReceiveMemoryWarning]; } @end
这时你发现运行的结果完全出乎你的意料(搓的无极限),如图:
原因分析:是将原是尺寸为W=128 * H=112
的图片拉伸成了W=200, H=50
; 解决方案: 1.找美工MM重做一张较大
的图片,这样的话就会出现软件包将来会变大,占用空间更大;如果我们要经常修改按钮的frame
,你是想让MM杀你的节奏~~,显然不可行; 2.苹果为我们提供了关于图片拉伸的API,我们可以直接利用代码实现,是不是很牛X;
利用苹果提供的API来拉伸图片(目前发现的有四种): 一、 方式一(iOS5之前): 如下图:设置topCapHeight
、leftCapWidth
、bottomCapHeight
、lerightCapWidth
,图中的黑色区域就是图片拉伸的范围,也就是说边上的不会被拉伸. 通过下面的方法我们可以设置:
// 官方API说明 // - stretchableImageWithLeftCapWidth:topCapHeight:(iOS 5.0) // Creates and returns a new image object with the specified cap values.
说明:这个方法只有2个参数,leftCapWidth
代表左端盖宽度,topCapHeight
代表上端盖高度。系统会自动计算
出右端盖宽度rightCapWidth
和底端盖高度bottomCapHeight
,算法如下:
1 2 3 4 5 rightCapWidth = image.width - leftCapWidth - 1 ; bottomCapHeight = image.height - topCapHeight - 1
这样一来,其实我们图片的可拉伸范围只有1 * 1
,所以再怎么拉伸都不会影响图片的外观; 具体代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 UIImage *image = [UIImage imageNamed:@"chat_send_nor" ];NSInteger leftCapWidth = image.size.width * 0.5 ;NSInteger topCapHeight = image.size.height * 0.5 ;UIImage *newImage = [image stretchableImageWithLeftCapWidth:leftCapWidth topCapHeight:topCapHeight];[btn setBackgroundImage:newImage forState:UIControlStateNormal ];
运行效果:
方式二:(iOS5) 利用下面的方法:
1 2 3 - (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets )capInsets NS_AVAILABLE_IOS (5 _0);
1 2 3 4 typedef struct UIEdgeInsets { CGFloat top, left, bottom, right; } UIEdgeInsets ;
说明:UIEdgeInsets
中的CGFloat top, left, bottom, right
就是用来设置上端盖、左端盖、下端盖、右端盖的尺寸(逆时针方向
);
具体代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 UIImage *image = [UIImage imageNamed:@"chat_send_nor" ];CGFloat top = image.size.height * 0.5 ;CGFloat left = image.size.width * 0.5 ;CGFloat bottom = image.size.height * 0.5 ;CGFloat right = image.size.width * 0.5 ;UIEdgeInsets edgeInsets = UIEdgeInsetsMake (top, left, bottom, right);UIImage *newImage = [image resizableImageWithCapInsets:edgeInsets];[btn setBackgroundImage:newImage forState:UIControlStateNormal ];
运行效果:
方式三:(iOS6) 利用下面的方法:
1 2 - (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets )capInsets resizingMode:(UIImageResizingMode )resizingMode NS_AVAILABLE_IOS (6 _0);
说明:相比iOS5中的方法多了一个resizingMode
参数
1 2 3 4 typedef NS_ENUM (NSInteger , UIImageResizingMode ) { UIImageResizingModeTile , UIImageResizingModeStretch , };
具体代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 UIImage *image = [UIImage imageNamed:@"chat_send_nor" ];CGFloat top = image.size.height * 0.5 ;CGFloat left = image.size.width * 0.5 ;CGFloat bottom = image.size.height * 0.5 ;CGFloat right = image.size.width * 0.5 ;UIEdgeInsets edgeInsets = UIEdgeInsetsMake (top, left, bottom, right);UIImageResizingMode mode = UIImageResizingModeStretch ;UIImage *newImage = [image resizableImageWithCapInsets:edgeInsets resizingMode:mode];[btn setBackgroundImage:newImage forState:UIControlStateNormal ];
运行效果:
方式4:(最简单的一种方式)
是不是So easy~~
运行效果:
备注:上面所有通过代码来拉伸图片的方法都是返回
一个拉伸后的新图片
.