iOS中拉伸图片的几种方式

假如下面的一张图片,是用来做按钮的背景图片的,原始尺寸是(128 * 112)

按钮背景图片.png

我们通过代码将这张图片设置为按钮的背景图片,假如我们将创建好的按钮的宽高设置为:(W=200, H=50)代码如下:

//
//  ViewController.m
//  iOS图片拉伸总结
//
//  Created by Sunshine on 15/6/29.
//  Copyright (c) 2015年 YotrolZ. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    // 创建一个按钮
    UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];

    // 设置按钮的frame
    btn.frame = CGRectMake(100, 300, 200, 50);

    // 加载图片
    UIImage *image = [UIImage imageNamed:@"chat_send_nor"];

    // 设置按钮的背景图片
    [btn setBackgroundImage:image forState:UIControlStateNormal];

    // 将按钮添加到控制器的view
    [self.view addSubview:btn];

}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

这是你发现运行的结果完全出乎你的意料(搓的无极限),如图:

运行效果图1.png

原因分析:是将原是尺寸为W=128 * H=112的图片拉伸成了W=200, H=50;
解决方案:
1.找美工MM重做一张较大的图片,这样的话就会出现软件包将来会变大,占用空间更大;如果我们要经常修改按钮的frame,你是想让MM杀你的节奏~~,显然不可行;
2.苹果为我们提供了关于图片拉伸的API,我们可以直接利用代码实现,是不是很牛X;

利用苹果提供的API来拉伸图片(目前发现的有四种):
一、 方式一(iOS5之前):
如下图:设置topCapHeightleftCapWidthbottomCapHeightlerightCapWidth,图中的黑色区域就是图片拉伸的范围,也就是说边上的不会被拉伸.
通过下面的方法我们可以设置:

// 官方API说明
// - stretchableImageWithLeftCapWidth:topCapHeight:(iOS 5.0)
// Creates and returns a new image object with the specified cap values.

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

// 系统会自动计算rightCapWidth
rightCapWidth = image.width - leftCapWidth - 1;  

// 系统会自动计算bottomCapHeight
bottomCapHeight = image.height - topCapHeight - 1

这样一来,其实我们图片的可拉伸范围只有1 * 1,所以再怎么拉伸都不会影响图片的外观;
具体代码如下:

    // 加载图片
    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];

运行效果:

运行效果图2.png

方式二:(iOS5)
利用下面的方法:

// 官方API说明
- (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets NS_AVAILABLE_IOS(5_0);
// create a resizable version of this image. the interior is tiled when drawn.
typedef struct UIEdgeInsets {
    CGFloat top, left, bottom, right;
    // specify amount to inset (positive) for each of the edges. values can be negative to ‘outset‘
} UIEdgeInsets;

说明:UIEdgeInsets中的CGFloat top, left, bottom, right就是用来设置上端盖、左端盖、下端盖、右端盖的尺寸(逆时针方向);

具体代码如下:

    // 加载图片
    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];

运行效果:

运行效果图3.png

方式三:(iOS6)
利用下面的方法:

- (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets resizingMode:(UIImageResizingMode)resizingMode NS_AVAILABLE_IOS(6_0);
// the interior is resized according to the resizingMode

说明:相比iOS5中的方法多了一个resizingMode参数

typedef NS_ENUM(NSInteger, UIImageResizingMode) {
    UIImageResizingModeTile, // 平铺模式,通过重复显示UIEdgeInsets指定的矩形区域来填充图片
    UIImageResizingModeStretch, // 拉伸模式,通过拉伸UIEdgeInsets指定的矩形区域来填充图片
};

具体代码如下:

    // 加载图片
    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.png

方式4:(最简单的一种方式)

设置slicing属性.png

设置后.png

是不是So easy~~

运行效果:

运行效果5.png

备注:上面所有通过代码来拉伸图片的方法都是返回一个拉伸后的新图片.

文/YotrolZ(简书作者)
原文链接:http://www.jianshu.com/p/c9cbbdaa9b02
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

时间: 2024-10-10 11:05:16

iOS中拉伸图片的几种方式的相关文章

ios中创建控制器的几种方式

1.通过storyboard创建: (1)先加载storyboard文件: UIStoryboard * storyboard = [UIStoryboard storyboardWithName:@"Test"  bundle:nil]; (2) 初始化storyboard中的控制器: ①初始化"初始控制器":HLViewController * hl = [storyboard instantiateInitialViewController]; ②通过标识初始

拉伸图片的几种方式

问题:当图片比较小,而图片框.或者按钮,比较大,图片填充整个按钮会导致变形,通过拉伸图片可以使得虽然拉伸而不变形. 拉伸处理后: 方式1.通过resizableImageWithCapInsets:resizingMode方法. - (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets resizingMode:(UIImageResizingMode)resizingMode NS_AVAILABLE_IOS(6_0);

vue-cli3中引入图片的几种方式和注意事项

如果你是在数据中引入图片,他是从项目中引入的应该按第一种方式引入 如果不是在数据中引入图片,按第二种方式引入 原文地址:https://www.cnblogs.com/jxnc/p/12266781.html

QF——iOS中数据持久化的几种方式

数据持久化的几种方式: 一.属性列表文件: .plist文件是种XML文件.数组,字典都可以和它互相转换. 读取plist文件生成数组:plist——>NSArray 把数组写入plist文件:NSArray——>plist 二.NSUserDefaults: 它是单例的.通过[NSUserDefaults standardUserDefaults];提供唯一的实例 NSUserDefaults存储数据,本质上就是属性列表plist文件里.只不过是系统提供的,存储位置固定的,它存储在沙盒的Li

IOS中延时执行的几种方式的比较和汇总

本文列举了四种延时执行某函数的方法及其一些区别.假如延时1秒时间执行下面的方法. - (void)delayMethod { NSLog(@"execute"); } 1.performSelector方法 [self performSelector:@selector(delayMethod) withObject:nil afterDelay:1.0f]; 此方式要求必须在主线程中执行,否则无效.是一种非阻塞的执行方式,暂时未找到取消执行的方法. 2.定时器:NSTimer [NS

iOS中延迟执行的几种方式

- 1.使用NSThread类 [NSThread sleepForTimeInterval:3]; 该方法会阻塞当前线程 -2.使用NSObject中的方法 [self performSelector:@selector(download:) withObject:sender afterDelay:timeDelay]; 该方法不会阻塞当前线程,在当前线程执行selector -3.使用gcd 在主线程或由全局队列上的线程异步延迟回调block dispatch_queue_t queue

IOS中实现动画的几种方式

1.UIView首末式动画(实现渐变效果) [UIView animateWithDuration:...] 在修改了自动布局的约束之后,执行下面代码实现动画效果 [UIView animateWithDuration:1.0 animations:^{ [添加了约束的view layoutIfNeeded]; }]; 2.UIImageView的startAnimating系列方法播放帧动画. 3.当对非Root Layer的部分属性(可动画属性)进行修改时,默认会自动产生一些动画效果(隐式动

IOS数据本地存储的四种方式--

注:借鉴于:http://blog.csdn.net/jianjianyuer/article/details/8556024 在IOS开发过程中,不管是做什么应用,都会碰到数据保存问题.将数据保存到本地,能够让程序更加流畅,不会出现让人厌恶的菊花状,使得用户的体验更好.下面是介绍数据保存的方式 第一.NSKeyedArchiver:采用归档的形式来保存数据.(归档——解档)———大量数据和频繁读写不合适使用 1.归档器的作用是将任意的对象集合转换为字节流.这听起来像是NSPropertyLis

ios页面间传递参数四种方式

ios页面间传递参数四种方式 1.使用SharedApplication,定义一个变量来传递. 2.使用文件,或者NSUserdefault来传递 3.通过一个单例的class来传递 4.通过Delegate来传递. IOS开发使用委托delegate在不同窗口之间传递数据是本文要介绍的内容,主要是来讲解如何使用委托delegate在不同窗口之间传递数据,具体内容来看详细内容.在IOS开发里两个UIView窗口之间传递参数方法有很多,比如 前面3种方法,暂且不说,这次主要学习如何使用通过Dele