现在的位置: 首页 > 综合 > 正文

resizableImageWithCapInsets实现登录按钮、胶囊tab按钮和聊天气泡贴图效果

2018年05月08日 ⁄ 综合 ⁄ 共 5430字 ⁄ 字号 评论关闭

1.关于UIImage的resizable capInsets属性

This technique is often used to create variable-width buttons, which retain the same rounded corners but whose center
region 
grows or shrinks as needed. 

For example, you can use this method to create a background image for a button withborders andcornerswhen
the button is 
resized, the corners of the image remain unchanged,
but the borders and center of the image 
expand to cover
the new size
.


当我们在创建变宽按钮时,往往保持按钮的圆角,只是让中心部分进行必要地伸缩。

例如,你可以使用stretchable或resizable来设置圆角按钮的背景贴图,当按钮尺寸发生改变时,背景贴图的圆角保持不变,中心部分进行必要伸缩来适应新的尺寸。


调用stretchableImage或resizableImage后,返回一个带有缩放封盖属性的UIImage对象(Return a new image object with the specified cap insets)。
当我们对超出图片size的UIImageView/UIButton进行setImage或setBackgroundImage时,就会按照预设CapInsets属性进行填充、拉伸适配

2.-[UIImage(UIImageDeprecated)stretchableImageWithLeftCapWidth:topCapHeight:]

NS_DEPRECATED_IOS(2_0, 5_0, "Use -resizableImageWithCapInsets:")
【Summary】
Creates and returns a new image object with the specified cap values.
【Discussion】

specifying cap insets such that the interior is a 1x1 area.

During scaling or resizing of the image, areas covered by a cap are not scaled or resized
Instead, the 1-pixel wide area not covered by the cap in each direction is what is scaled or resized

【解说】
    它的功能是创建一个内容可拉伸,而边角不拉伸的图片,需要两个参数:

@property(nonatomic,readonlyNSInteger leftCapWidth:horiz.
stretchable. 左边不拉伸区域的宽度。

@property(nonatomic,readonlyNSInteger topCapHeight:vert.
stretchable. 上面不拉伸区域的高度。

    根据UIKit/UIImage.h对该属性的描述

  •     rightCapWidth=width-leftCapWidth-1
  •     bottomCapHeight=height-topCapWidth-1

    UIEdgeInsets capInsets =  UIEdgeInsetsMake(topCapHeight,leftCapWidth,bottomCapHeight,rightCapWidth)

    因此,实际stretchable的interior area是capInsets封盖圈起来的部分——一个1x1点阵。也即坐标为{left+1,top+1}的这个点(one
point)会像贴瓷砖那样进行复制(UIImageResizingModeTile:the interior is tiled when drawn),capInsets封盖的周边外围保持不变。

    为视效均匀起见,一般选取图片的中心点(leftCapWidth=width/2,topCapHeight=height/2)进行复制填充。

// create a resizable version of this image. the interior is tiled when drawn.

3.-[UIImageresizableImageWithCapInsets:]

@property(nonatomic,readonly)UIEdgeInsetscapInsets;

NS_AVAILABLE_IOS(5_0)

【Summary】
create a resizable version of this image. the interior is tiled when drawn.
【Discussion】

For best performance, use a tiled area that is a 1x1 pixel area in size.

iOS uses different rendering techniques, with differentperformance characteristics, depending on the size of each resizable
area
in the image:

  • If resizable areas have a width or height of1 pixel—that is, a horizontally resizable area is 1 pixel wide, avertically resizable
    area is 1 pixel tall, or the center region of the image is 1 x 1 pixel—iOS draws the image by stretching the 1-pixel region. This mode provides the fastest
    performance
    (for nonzero cap insets).
  • If resizable areas have a width or heightgreater than 1 pixel, iOS draws the image by tiling the region. This mode providesreduced performance,
    but can be useful for images with textured (rather than solid-color) content in their resizable areas.
  • If the
    entire
    image is resizable—that is, the capInsets parameter is UIEdgeInsetsZero—and its size is greater than 1 x 1 pixel, iOS draws the image by tiling
    the entire image. This mode is faster than the tiling mode for nonzero cap insets.

【解说】
    其中UIEdgeInsets参数的格式是(top,left,bottom,right),从上、左、下、右分别在图片上画了一道线,这样就给一个图片加了一个框,只有在框里面的部分才会被拉伸框外面的封盖部分则不会改变

    选取图片的中心点(height/2,width/2,height/2-1,width/2-1)进行复制填充时,效果同stretchableImageWithLeftCapWidth:width/2 topCapHeight:height/2,对1x1 pixel area进行拉伸(stretching)适配。对于纯色图片,选取中心点拉伸效能最优。

    若capInsets封盖部分的区域大于1x1,则对尺寸超出部分,像贴瓷砖一样复制填充(tile/spread/extend)。对于纹理贴图(textured),通常采用此种方式。


// the interior is resized according to the resizingMode

4.-[UIImage resizableImageWithCapInsets:resizingMode:]

NS_AVAILABLE_IOS(6_0)
================================================================================
【Discussion】

This method is exactly the same as its counterpart resizableImageWithCapInsets:except that the resizing mode of the new image
object can be explicitly declared

You should
only
call this method in place of its counterpart if you specifically want your image to be resized with the UIImageResizingModeStretch resizing mode.

【解说】
    UIImageResizingModeTile:平铺模式,通过拉伸或铺排UIEdgeInsets指定的矩形区域来填充图片

       resizableImageWithCapInsets: resizingMode:UIImageResizingModeTile相当于resizableImageWithCapInsets: ,一般直接调用resizableImageWithCapInsets:。

   
UIImageResizingModeStretch
:拉伸模式,通过拉伸UIEdgeInsets指定的矩形区域来填充图片
        拉伸UIEdgeInsets排除外围指定的内部矩形区域(interior resizable area is a rectangle)。
        横向拉伸:UIEdgeInsetsMake(0, coreRadius, 0, coreRadius),例如圆角/横向胶囊按钮贴图。

        纵向拉伸:UIEdgeInsetsMake(coreRadius, 0, coreRadius, 0),例如类似温度计的圆角/纵向胶囊按钮贴图。

        半角拉伸:UIEdgeInsetsMake(coreRadius, coreRadius,coreRadius,
coreRadius),例如带corner的圆角登录按钮。


5.综合例程

    例如,我们要用贴图top_half_bg@2x.png(39x20)和贴图bot_half_bg@2x.png(39x20) 实现如下贴图效果:


    其中分割线上半部由top_half_bg@2x.png贴出顶部圆角效果,分割线下半部由bot_half_bg@2x.png贴出底部圆角效果。其拉伸属性设置代码如下:

// 圆角半径为7pixel=3.5point
#define CORNER_RADIUS 4
// top_half_bg@2x.png拉伸矩形区域
#define TOP_STRETCH_CAP_INSETS  UIEdgeInsetsMake(CORNER_RADIUS,CORNER_RADIUS,0,CORNER_RADIUS)
// bot_half_bg@2x.png拉伸矩形区域
#define BOT_STRETCH_CAP_INSETS  UIEdgeInsetsMake(0,CORNER_RADIUS,CORNER_RADIUS,CORNER_RADIUS)

UIImage* topBgImage = [UIImage imageNamed:@”top_half_bg.png”];
topBgImage = [topBgImage resizableImageWithCapInsets:TOP_STRETCH_CAP_INSETS];

UIImage* botBgImage = [UIImage imageNamed:@”bot_half_bg.png”];
botBgImage = [botBgImage resizableImageWithCapInsets:BOT_STRETCH_CAP_INSETS];

    最后,给出一个关于UIImageView和UIButton贴图的综合示例(fan2/resizableImage):

    (1)第一组:上边一个左上、右上带圆角贴图,下边一个左下、右下带圆角贴图。

    (2)第二组:登录按钮,四角圆角贴图。

    (3)第三组:微信聊天气泡贴图效果。

    (4)第四组:横向胶囊圆角按钮贴图示例:

  • 初始胶囊按钮,背景为蓝圈白底,字体为蓝色。
  • 左右按钮初始图标分别为大拇指竖起和大拇指向下。 
  • 选择左胶囊按钮,背景变蓝,字体变白,图标由大拇指竖起变为一朵鲜花。 
  • 选择右胶囊按钮,背景变蓝,字体变白,图标由大拇指向下变为一朵枯萎。 

    以下为UIImageView和UIButton贴图的CapInsets标注:

参考:

iOS图片拉伸技巧

[UIImage
resizableImageWithCapInsets:]使用注意

iOS 不规则的ImageView》《iOS
实现聊天剪裁气泡

抱歉!评论已关闭.