iOS-圖片拉伸技巧

iOS開發中咱們會遇到漸變的背景,內容可變的流式標籤,聊天氣泡(QQ聊天氣泡),因爲內容是可變的,寬度和高度一樣可變,這樣就是致使每次出現的尺寸與以前不同。若是是須要設置的比較的多,估計美工會煩死,一樣也會額外增長的內存開銷,因此這個知道一點圖片拉伸的技巧會師咱們的能使咱們APP更加高效,代碼更加簡潔,事半功倍~從設置的角度來有四種方法能夠實現~git

Assets設置

首先咱們有一個不規則的氣泡按鈕,大小是35*30,Slices選中水平和垂直方向的距離,寬高設置爲1github

  

設置完成之,咱們設置Button的背景圖片看下加載效果:ide

    UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(80, 100, 100, 40)];
    UIImage *buttonImage = [UIImage imageNamed:@"Question"];
    [button setTitle:@"默認" forState:UIControlStateNormal];
    [button addTarget:self action:@selector(buttonPressed:) forControlEvents: UIControlEventTouchUpInside];
    [button setBackgroundImage:buttonImage forState:UIControlStateNormal];
    [self.view addSubview:button];

模擬器加載效果:this

 

第一個圖片是咱們須要加載效果,若是咱們將Slices設置爲None,咱們看到的效果是這樣的:atom

看到這裏是否是感受有點興趣了,爲何設置了上面的選項就能夠出現平鋪的效果,稍微思考一下,咱們在下面的一種方式中將找到答案~spa

iOS5以前的設置

上圖的第二個按鈕是咱們經過代碼設置,不是在Assets中設置,咱們先來看一下實現代碼:code

    //35*30
    UIButton *nextButton = [[UIButton alloc] initWithFrame:CGRectMake(80, 180, 100, 40)];
    [nextButton setTitle:@"iOS5以前" forState:UIControlStateNormal];
    nextButton.layer.borderColor=[[UIColor redColor] CGColor];
    nextButton.layer.borderWidth=1.0f;
    UIImage *image = [UIImage imageNamed:@"Question"];
    // 設置左邊端蓋寬度  rightCap=width - leftCapWidth - 1
    NSInteger leftCapWidth = image.size.width * 0.5;
    // 設置上邊端蓋高度  bottom=height - topCapWidth - 1
    NSInteger topCapHeight = image.size.height * 0.5;
    UIImage *newImage = [image stretchableImageWithLeftCapWidth:leftCapWidth topCapHeight:topCapHeight];
    [nextButton setBackgroundImage:newImage forState:UIControlStateNormal];
    [self.view addSubview:nextButton];

新建圖片,設置按鈕的背景圖片,與通常設置沒有什麼區別,不過多了stretchableImageWithLeftCapWidth:方法,咱們看一下API說明:orm

@interface UIImage(UIImageDeprecated)

// use resizableImageWithCapInsets: and capInsets.

- (UIImage *)stretchableImageWithLeftCapWidth:(NSInteger)leftCapWidth topCapHeight:(NSInteger)topCapHeight __TVOS_PROHIBITED;
@property(nonatomic,readonly) NSInteger leftCapWidth __TVOS_PROHIBITED;   // default is 0. if non-zero, horiz. stretchable. right cap is calculated as width - leftCapWidth - 1
@property(nonatomic,readonly) NSInteger topCapHeight __TVOS_PROHIBITED;   // default is 0. if non-zero, vert. stretchable. bottom cap is calculated as height - topCapWidth - 1

@end

咱們須要設置拉伸區域具體圖片的上方和左邊的距離:blog

strechWidth=width-leftCapWidth-(width-leftCapWidth-1)=1圖片

strechHeight=height-rightCaopWidth-(height - topCapWidth - 1)=1

因此咱們拉伸的區域是1*1,關於上面的leftCapWidth有人可能內心有疑問,爲何leftCapWidth = image.size.width * 0.5,爲何是0.5?本身最開始隨便設置一個距離結果圖片醜的要死,好比說咱們左邊設置0.2,上邊設置爲0.8,咱們看到的效果是這樣的:

 

這是極端狀況,默認的狀況下無論圖片是如何的規則,中間的1*1區域是正方形,若是按照上面設置,咱們會發現,上下左右四個點組成的圖片是極其不規則,所以建議設置在中間,不過有的是有偏離一些也沒有太多問題,好比說0.4,0.6對於比例設置你們若是有興趣的能夠以後下載代碼,自行研究~

iOS5設置

stretchableImageWithLeftCapWidth在iOS5以後已經廢棄,咱們能夠經過resizableImageWithCapInsets來設置上下左右邊距~

resizableImageWithCapInsets與以前的方法同樣,一樣是經過重置產生新的圖片:

- (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets NS_AVAILABLE_IOS(5_0); // create a resizable version of this image. the interior is tiled when drawn.

UIEdgeInsets基本上UI中比較常見:

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;

圖片效果參考模擬器的第三個按鈕,設置代碼以下:

     UIImage *image = [UIImage imageNamed:@"Question"];
    UIButton  *resizableButton=[[UIButton alloc]initWithFrame:CGRectMake(80, 250, 100, 40)];
    [resizableButton setTitle:@"iOS5" forState:UIControlStateNormal];
    // 設置端蓋的值
    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 *edgeImage = [image resizableImageWithCapInsets:edgeInsets];
    //背景圖片
    [resizableButton setBackgroundImage:edgeImage forState:UIControlStateNormal];
    [self.view addSubview:resizableButton];

iOS6設置

iOS6的設置方法和iOS5差很少,多了一個參數UIImageResizingMode:

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

UIImageResizingMode說明:

typedef NS_ENUM(NSInteger, UIImageResizingMode) {
    UIImageResizingModeTile,平鋪模式,經過重複顯示UIEdgeInsets指定的矩形區域來填充圖片
UIImageResizingModeStretch, };拉伸模式,經過拉伸UIEdgeInsets指定的矩形區域來填充圖片

實際效果參考上圖中的最後一個按鈕:

    UIImage *image = [UIImage imageNamed:@"Question"];
    UIButton  *resizableButtonMode=[[UIButton alloc]initWithFrame:CGRectMake(80, 320, 180, 40)];
    [resizableButtonMode setTitle:@"iOS6" forState:UIControlStateNormal];
    [resizableButtonMode addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
    // 設置上左下右邊距
    CGFloat topMode= image.size.height * 0.5;
    CGFloat leftMode= image.size.width * 0.5;
    CGFloat bottomMode= image.size.height * 0.5;
    CGFloat rightMode= image.size.width * 0.5;
    
    UIEdgeInsets edgeInsetsMode= UIEdgeInsetsMake(topMode, leftMode, bottomMode, rightMode);
    
    // 拉伸圖片
    UIImage *edgeModeImage = [image resizableImageWithCapInsets:edgeInsetsMode resizingMode:UIImageResizingModeStretch];
//    UIImage *edgeModeImage = [image resizableImageWithCapInsets:edgeInsetsMode resizingMode:UIImageResizingModeTile];
    
    //設置圖片
    [resizableButtonMode setBackgroundImage:edgeModeImage forState:UIControlStateNormal];
    [self.view addSubview:resizableButtonMode];

 項目GitHub地址:https://github.com/SmallElephant/iOS-FEImageStrech

相關文章
相關標籤/搜索