2012-01-16 30 views
24

Tôi đang cố kéo giãn hình mũi tên điều hướng trong khi vẫn giữ các cạnh sao cho phần giữa trải dài và các đầu được cố định.Kéo giãn UIImage trong khi vẫn giữ các góc

Dưới đây là hình ảnh mà tôi đang cố gắng để kéo dài:

enter image description here

iOS sau 5 mã cho phép hình ảnh khi thay đổi kích cỡ để căng các phần trung tâm của hình ảnh được định nghĩa bởi UIEdgeInsets.

[[UIImage imageNamed:@"arrow.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(15, 7, 15, 15)]; 

Điều này dẫn đến một hình ảnh trông như thế này (nếu khung của hình ảnh được thiết lập đến 70 pixel rộng):

enter image description here

Điều này thực sự là những gì tôi muốn nhưng resizableImageWithCapInsets chỉ được hỗ trợ trên iOS 5 trở lên.

Trước khi iOS 5 phương pháp tương tự duy nhất là stretchableImageWithLeftCapWidth:topCapHeight nhưng bạn chỉ có thể chỉ định các insets trên cùng và bên trái có nghĩa là hình ảnh phải có cạnh hình bằng nhau.

Có cách nào để thay đổi kích thước hình ảnh iOS 4 giống như phương pháp resizableImageWithCapInsets của iOS 5 hay cách khác để thực hiện việc này?

Trả lời

28

giả định của bạn ở đây là sai:

Trước khi iOS 5 chỉ có phương pháp tương tự là stretchableImageWithLeftCapWidth: topCapHeight nhưng bạn chỉ có thể xác định đỉnh và insets trái có nghĩa là hình ảnh phải có cạnh hình bằng nhau.

Các mũ được chỉ ra như sau - Tôi sẽ đi qua nắp bên trái, nhưng nguyên tắc tương tự áp dụng cho giới hạn trên cùng.

Giả sử hình ảnh của bạn rộng 20px.

  • Chiều rộng nắp trái - đây là phần ở phía bên trái của hình ảnh không thể kéo dài. Trong phương thức stretchableImage bạn gửi giá trị 10 cho điều này.
  • Phần có thể kéo dài - điều này được giả định là một pixel chiều rộng, do đó, nó sẽ là các pixel trong cột "11", muốn có mô tả tốt hơn
  • Điều này có nghĩa là có giới hạn bên phải của 9px còn lại hình ảnh của bạn - điều này cũng sẽ không bị bóp méo.

này được lấy từ các mũ End documentation

leftCapWidth

chỉ định một phần của một hình ảnh mà không cần phải thay đổi kích cỡ khi một hình ảnh được kéo dài. Kỹ thuật này được sử dụng để triển khai các nút và các yếu tố giao diện dựa trên hình ảnh có thể thay đổi kích thước khác. Khi nút có mũ kết thúc được thay đổi kích thước, việc thay đổi kích thước chỉ xảy ra ở giữa nút, trong vùng giữa các mũ kết thúc. Các mũ cuối cùng giữ nguyên kích thước và ngoại hình ban đầu của chúng.

Thuộc tính này chỉ định kích thước của nắp đầu bên trái.Phần giữa (có thể kéo dài) được giả định là rộng 1 pixel. Do đó, nắp cuối bên phải được tính toán bằng cách thêm kích thước của nắp đầu bên trái và phần giữa lại với nhau và sau đó trừ đi giá trị mà từ chiều rộng của hình ảnh:

rightCapWidth = image.size.width - (image.leftCapWidth + 1);

+0

Vâng tôi đã xóa phiên bản iOS 5 và hiện đang sử dụng hình ảnh có thể kéo dài vì chúng tôi cần hỗ trợ cho các thiết bị chạy iOS4. Cảm ơn. – Camsoft

2

dụ của bạn là hoàn toàn có thể sử dụng stretchableImageWithLeftCapWidth:topCapHeight: với nắp bên trái là 15 (hiển nhiên, từ đọc mã của bạn). Điều đó sẽ kéo ngang nút bằng cách lặp lại cột giữa.

3

Bạn có thể mở rộng UIImage để cho phép kéo dài một hình ảnh với bảo vệ cạnh tùy chỉnh (do đó kéo dài phần bên trong của hình ảnh, thay vì ốp lát nó):

UIImage + utils.h:

#import <UIKit/UIKit.h> 
@interface UIImage(util_extensions) 
//extract a portion of an UIImage instance 
-(UIImage *) cutout: (CGRect) coords; 
//create a stretchable rendition of an UIImage instance, protecting edges as specified in cornerCaps 
-(UIImage *) stretchImageWithCapInsets: (UIEdgeInsets) cornerCaps toSize: (CGSize) size; 
@end 

UIImage + utils.m:

#import "UIImage+utils.h" 
@implementation UIImage(util_extensions) 
-(UIImage *) cutout: (CGRect) coords { 
    UIGraphicsBeginImageContext(coords.size); 
    [self drawAtPoint: CGPointMake(-coords.origin.x, -coords.origin.y)]; 
    UIImage *rslt = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    return rslt; 
} 

-(UIImage *) stretchImageWithCapInsets: (UIEdgeInsets) cornerCaps toSize: (CGSize) size { 
    UIGraphicsBeginImageContext(size); 

    [[self cutout: CGRectMake(0,0,cornerCaps.left,cornerCaps.top)] drawAtPoint: CGPointMake(0,0)]; //topleft 
    [[self cutout: CGRectMake(self.size.width-cornerCaps.right,0,cornerCaps.right,cornerCaps.top)] drawAtPoint: CGPointMake(size.width-cornerCaps.right,0)]; //topright 
    [[self cutout: CGRectMake(0,self.size.height-cornerCaps.bottom,cornerCaps.left,cornerCaps.bottom)] drawAtPoint: CGPointMake(0,size.height-cornerCaps.bottom)]; //bottomleft 
    [[self cutout: CGRectMake(self.size.width-cornerCaps.right,self.size.height-cornerCaps.bottom,cornerCaps.right,cornerCaps.bottom)] drawAtPoint: CGPointMake(size.width-cornerCaps.right,size.height-cornerCaps.bottom)]; //bottomright 

    [[self cutout: CGRectMake(cornerCaps.left,0,self.size.width-cornerCaps.left-cornerCaps.right,cornerCaps.top)] 
drawInRect: CGRectMake(cornerCaps.left,0,size.width-cornerCaps.left-cornerCaps.right,cornerCaps.top)]; //top 

    [[self cutout: CGRectMake(0,cornerCaps.top,cornerCaps.left,self.size.height-cornerCaps.top-cornerCaps.bottom)] 
drawInRect: CGRectMake(0,cornerCaps.top,cornerCaps.left,size.height-cornerCaps.top-cornerCaps.bottom)]; //left 

    [[self cutout: CGRectMake(cornerCaps.left,self.size.height-cornerCaps.bottom,self.size.width-cornerCaps.left-cornerCaps.right,cornerCaps.bottom)] 
drawInRect: CGRectMake(cornerCaps.left,size.height-cornerCaps.bottom,size.width-cornerCaps.left-cornerCaps.right,cornerCaps.bottom)]; //bottom 

    [[self cutout: CGRectMake(self.size.width-cornerCaps.right,cornerCaps.top,cornerCaps.right,self.size.height-cornerCaps.top-cornerCaps.bottom)] 
drawInRect: CGRectMake(size.width-cornerCaps.right,cornerCaps.top,cornerCaps.right,size.height-cornerCaps.top-cornerCaps.bottom)]; //right 

    [[self cutout: CGRectMake(cornerCaps.left,cornerCaps.top,self.size.width-cornerCaps.left-cornerCaps.right,self.size.height-cornerCaps.top-cornerCaps.bottom)] 
drawInRect: CGRectMake(cornerCaps.left,cornerCaps.top,size.width-cornerCaps.left-cornerCaps.right,size.height-cornerCaps.top-cornerCaps.bottom)]; //interior 

    UIImage *rslt = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    return [rslt resizableImageWithCapInsets: cornerCaps]; 
} 

@end 
8
UIImage *image = [UIImage imageNamed:@"img_loginButton.png"]; 
    UIEdgeInsets edgeInsets; 
    edgeInsets.left = 0.0f; 
    edgeInsets.top = 0.0f; 
    edgeInsets.right = 5.0f; //Assume 5px will be the constant portion in your image 
    edgeInsets.bottom = 0.0f; 
    image = [image resizableImageWithCapInsets:edgeInsets]; 
//Use this image as your controls image 
0

Swift phiên bản 3.0 của câu trả lời của Vicky.

var imageInset:UIEdgeInsets = UIEdgeInsets() 
     imageInset.left = 10.0 
     imageInset.top = 10.0 
     imageInset.bottom = 10.0 
     imageInset.right = 10.0 
     self.myImageView.image = myimage.resizableImage(withCapInsets: imageInset) 
Các vấn đề liên quan