Подтвердить что ты не робот

Растяжение UIImage при сохранении углов

Я пытаюсь растянуть изображение стрелки навигации, сохраняя края так, чтобы средний участок и концы были зафиксированы.

Вот изображение, которое я пытаюсь растянуть:

enter image description here

Следующий код iOS 5 позволяет изменять размер изображения, чтобы растянуть центральные части изображения, определенные в UIEdgeInsets.

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

В результате получается изображение, которое выглядит так (если размер кадра изображения равен 70 пикселям):

enter image description here

Это на самом деле то, что я хочу, но resizableImageWithCapInsets поддерживается только на iOS 5 и более поздних версиях.

До iOS 5 единственным подобным методом является stretchableImageWithLeftCapWidth:topCapHeight, но вы можете указать только верхнюю и левую вставки, что означает, что изображение должно имеют одинаковые кромки формы.

Есть ли способ iOS 4 изменить размер изображения так же, как и метод iOS 5 resizableImageWithCapInsets, или другой способ сделать это?

4b9b3361

Ответ 1

Ваше предположение здесь неверно:

До iOS 5 единственный подобный метод растягиваетсяImageWithLeftCapWidth: topCapHeight, но вы можете указать только верхнюю и левую вставки , что означает, что изображение должно иметь одинаковые ребра формы.

Крышки вычисляются следующим образом: я пройду через левую крышку, но тот же принцип применяется к верхней крышке.

Скажите, что ваше изображение имеет ширину 20 пикселей.

  • Ширина левого крыла - это часть с левой стороны изображения, которое невозможно растянуть. В методе stretchableImage вы отправляете для этого значение 10.
  • Растяжимая часть - предполагается, что она имеет ширину в один пиксель, поэтому она будет пикселями в столбце "11", если не будет лучшего описания.
  • Это означает, что имеется правая крышка оставшегося 9px вашего изображения - это также не будет искажено.

Это взято из documentation

leftCapWidth

Конечные колпачки определяют часть изображения, которое не должно изменяться при растяжении изображения. Этот метод используется для реализации кнопок и других изменяемых по размеру элементов интерфейса на основе изображений. Когда изменяется размер кнопки с конечными колпачками, изменение размера происходит только в середине кнопки в области между концевыми крышками. Конечные колпачки сами сохраняют свой первоначальный размер и внешний вид.

Это свойство определяет размер левого торца. Средняя (растяжимая) часть считается шириной в 1 пиксель. Поэтому правая торцевая крышка вычисляется путем добавления размера левой торцевой крышки и средней части вместе, а затем вычитания этого значения из ширины изображения:

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

Ответ 2

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

Ответ 3

Вы можете расширить UIImage, чтобы позволить растягивать изображение с настраиваемой защитой края (тем самым растягивая внутреннюю часть изображения, а не разбивая его):

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

Ответ 4

Ваш пример вполне возможен, используя stretchableImageWithLeftCapWidth:topCapHeight: с левой крышкой 15 (видимо, от чтения вашего кода). Это будет горизонтально растягивать кнопку, повторяя средний столбец.

Ответ 5

Swift 3.0 версия ответа Вики.

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)