Objective c 构建具有多个可拉伸图像的UIImage

Objective c 构建具有多个可拉伸图像的UIImage,objective-c,ios,uiimage,drawing,core-graphics,Objective C,Ios,Uiimage,Drawing,Core Graphics,我有三张图片,一张左帽,一张右帽,一张中间。也许使用CGImageRefs(?),是否有一种基于CGRect构建位图的方法,该方法将中心块置于某个容器中,拉伸左盖,直到它到达中心块,然后拉伸右盖,生成UIImage 你的方法很奇怪:) 您有三个不同的图像组成一个可拉伸图像,但每次必须以某种方式使用它时,您都希望以编程方式构建它。这会浪费cpu周期。 iOS框架允许您像往常一样拉伸图像。在图像编辑器(Photoshop或类似工具)中打开文件。合成一个包含中心图像的单个图像,中心图像由左帽和右帽包围

我有三张图片,一张左帽,一张右帽,一张中间。也许使用
CGImageRefs
(?),是否有一种基于
CGRect
构建位图的方法,该方法将中心块置于某个容器中,拉伸左盖,直到它到达中心块,然后拉伸右盖,生成
UIImage

你的方法很奇怪:)

您有三个不同的图像组成一个可拉伸图像,但每次必须以某种方式使用它时,您都希望以编程方式构建它。这会浪费cpu周期。 iOS框架允许您像往常一样拉伸图像。在图像编辑器(Photoshop或类似工具)中打开文件。合成一个包含中心图像的单个图像,中心图像由左帽和右帽包围

现在,您可以像其他图像一样使用此图像,也可以像使用UIImage方法一样拉伸它

- (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets
UIEdgeInsets是一个简单的结构,用于确定您的上限。因此,假设你必须向左拉伸15磅,向右拉伸20磅,你的插图将是: 排名:0 按钮:0 左:15 右:20

就这样


详情请参阅。这篇文章讨论了iOS 5.0及以上版本中的一种不推荐的方法,但背后的理论是相同的。

我说只需按编程方式进行,是的,它可能会浪费一些CPU周期,但会更有趣

好了,我们开始

让我们在标题中定义3个UIImageView

UIImageView *left;
UIImageView *center;
UIImageView *right;
在viewDidLoad中,我们将创建它们

left = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"left.jpg"]];
center = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"center.jpg"]];
right = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"right.jpg"]];


[self.view addSubview:left];
[self.view addSubview:center];
[self.view addSubview:right];

//set the position of the center piece wherever you like, whatever size is right for your arrow
[self setCenterFrame:CGRectMake(100,100,100,100)]; //we'll make this function below
然后,让我们制作一种方法,您可以使用该方法设置中心图像的位置,并使其他图像在适当的位置来回摆动,将其自身拉伸到左右边缘

-(void)setCenterFrame:(CGRect)rect
{
    center.frame = rect; // this is your arrow

    //set size of left
    left.frame = CGRectMake(0,rect.origin.y, rect.origin.x, rect.size.height);

    //work out how much space there is to the right
    float sizeToTheRight = (self.view.bounds.size.width - rect.size.width) - rect.origin.x ;

    //set size of right
    right.frame = CGRectMake(rect.size.width + rect.origin.x,rect.origin.y, sizeToTheRight, rect.size.height);


}

好的,我按照承诺查了一下。以下是一个解决方案:

基本思想
  • 取左瓶盖,将右侧拉伸,制作一个
    UIImage
  • 用箭头“粘”它
    UIImage
  • 现在用右边的帽子粘上,左边拉长
这是一个小图片,我认为它可以

  ______ ........    ________      .........___________
 {______|........|  | arrow  |    |.........|__________)
left cap|lc flex     --------      rc flex  | right cap
代码 替代方案
受Jonathan Plaketts启发,同样的答案应该可以通过
UIImageViews
和如上拉伸UIImages来实现。

为什么不使用一个图像来代替呢?中间部分有一个无法拉伸的箭头。最终的图像是一个需要可拉伸宽度的地图注释标注。你是否尝试使用@Pfitz的意思是,你可以从一个图像获得此功能,你不需要拆分它。@borrden我想他知道这一点。但是中间的内容将被“正常”的方法所拉伸,他不想要这个。这个方法的问题是图像的中心部分会被拉伸。如果你读了问题下面的评论,他会清楚地说中间的图像是一个箭头。我认为他不希望它被拉伸;)刚尝试完,但没有成功。除非有一种方法在像这样的图像中间重复两段像素,而不影响中心的清洁方式,这样可以使箭头图像分离。如前所述拉伸可拉伸图像,然后使用UIGraphicsBeginImageContextWithOptions合成新图像使用drawAtPoint:UIImage方法将两个图像合成到上下文中,使用UIGraphicsGetImageFromCurrentImageContext从上下文中获取新图像,然后使用UIGraphicsSendImageContext关闭图形上下文。我认为这个答案完全没有用。仔细阅读问题,开始吧!老兄,太谢谢你了!我一整天都在尝试一百万种不同的解决方案。它似乎没有解决主要问题:如果你设置具体的宽度/高度值,程序将如何拉伸这个图像?如果您想说我可以更改硬编码的值,那么如果在拉伸后仍然必须定义混凝土尺寸区域,为什么要使用自动拉伸?
// get the images from disk
UIImage *leftCap = [UIImage imageNamed:@"leftCap.png"];
UIImage *arrow = [UIImage imageNamed:@"arrow.png"];
UIImage *rightCap = [UIImage imageNamed:@"rightCap"];

// stretch left and right cap
// calculate the edge insets beforehand !

UIImage *leftCapStretched = [leftCap resizableImageWithCapInsets:UIEdgeInsetsMake(topInset, leftInset, bottomInset, rightInset)];
UIImage *rightCapStretched = [rightCap resizableImageWithCapInsets:UIEdgeInsetsMake(topInset, leftInset, bottomInset, rightInset)];

CGFloat widthOfAllImages = leftCapStretched.size.width + arrow.size.width + rightCapStretched.size.width;

// build the actual glued image

UIGraphicsBeginImageContextWithOptions(CGSizeMake(widthOfAllImages, arrow.size.height), NO, 0);
[leftCapStretched drawAtPoint:CGPointMake(0, 0)];
[arrow drawAtPoint:CGPointMake(leftCap.size.width, 0)];
[rightCapStretched drawAtPoint:CGPointMake(leftCap.size.width + arrow.size.width, 0)];
UIImage* im = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext();

// now you should have a ready to use UIImage ;)