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

Как растянуть UIImageView без растягивания центра?

enter image description here

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

4b9b3361

Ответ 1

Используйте Photoshop или другой инструмент для редактирования изображений, чтобы разбить изображение на две части: край и центр. Краевое изображение может иметь ширину в один пиксель и использоваться для левого и правого краев; центр, однако, много пикселей в ширину, которые захватывают стрелку. Затем вы можете разместить три экземпляра UIImageView рядом друг с другом: левый край, центр и правый край. Левый и правый края изменяются до нужной ширины, а центр сохраняет свои первоначальные размеры.

Ответ 2

Если вам не нравится беспокоить Photoshop, и если изображение не должно динамически изменяться, вы можете использовать мой метод категории в UIImage.

Ваше образное изображение с именем "17maA.png" имеет ширину 124 px. Таким образом, вы можете легко создать версию шириной 300 пикселей с этим:

UIImage *image = [UIImage imageNamed:@"17maA"];
UIImage *newImage = [image pbResizedImageWithWidth:300 andTiledAreaFrom:10 to:20 andFrom:124-20 to:124-10];

Это метод категории:

- (UIImage *)pbResizedImageWithWidth:(CGFloat)newWidth andTiledAreaFrom:(CGFloat)from1 to:(CGFloat)to1 andFrom:(CGFloat)from2 to:(CGFloat)to2  {
    NSAssert(self.size.width < newWidth, @"Cannot scale NewWidth %f > self.size.width %f", newWidth, self.size.width);

    CGFloat originalWidth = self.size.width;
    CGFloat tiledAreaWidth = (newWidth - originalWidth)/2;

    UIGraphicsBeginImageContextWithOptions(CGSizeMake(originalWidth + tiledAreaWidth, self.size.height), NO, self.scale);

    UIImage *firstResizable = [self resizableImageWithCapInsets:UIEdgeInsetsMake(0, from1, 0, originalWidth - to1) resizingMode:UIImageResizingModeTile];
    [firstResizable drawInRect:CGRectMake(0, 0, originalWidth + tiledAreaWidth, self.size.height)];

    UIImage *leftPart = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    UIGraphicsBeginImageContextWithOptions(CGSizeMake(newWidth, self.size.height), NO, self.scale);

    UIImage *secondResizable = [leftPart resizableImageWithCapInsets:UIEdgeInsetsMake(0, from2 + tiledAreaWidth, 0, originalWidth - to2) resizingMode:UIImageResizingModeTile];
    [secondResizable drawInRect:CGRectMake(0, 0, newWidth, self.size.height)];

    UIImage *fullImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return fullImage;
}

Ответ 3

(Не очень помогает, но есть поддержка для противоположного: растяжение центра изображения и сохранение краевых частей того же размера: см. Растяжение UIImage при сохранении углов.)

Чтобы создать собственное решение,, вы можете создать компонент, содержащий три части: левое изображение, центральное изображение, правильное изображение. Затем вы обрабатываете изменения размера вашего компонента, гарантируя, что центральная часть остается той же ширины, а левые/правые компоненты (изображения) растягиваются.

Альтернативная стратегия: создать компонент, состоящий из двух изображений, уложенных друг на друга. Нижнее изображение представляет собой бит плоского стержня (без треугольника) и растягивается горизонтально, чтобы заполнить доступное пространство. Верхнее изображение представляет собой центральную часть треугольника и центрируется в доступном пространстве. Это даст эффект, который вы ищете.

Кроме того, есть приложение (не бесплатное!), которое поможет вам создавать приятные компоненты с растяжимыми качествами: PaintCode.

Ответ 4

Klaas ответ действительно помог мне, то же самое в Swift 3.0:

static func stretchImageSides(image: UIImage, newWidth: CGFloat) -> UIImage? {
    guard image.size.width < newWidth else {
        return image
    }

    let originalWidth = image.size.width
    let tiledAreaWidth = ceil(newWidth - originalWidth) / 2.0;

    UIGraphicsBeginImageContextWithOptions(CGSize(width: originalWidth + tiledAreaWidth, height: image.size.height),
                                           false, image.scale)

    let firstResizable = image.resizableImage(withCapInsets: UIEdgeInsets(top: 0,
                                                                          left: 0,
                                                                          bottom: 0,
                                                                          right: originalWidth - 3),
                                              resizingMode: .stretch)
    firstResizable.draw(in: CGRect(x: 0, y: 0, width: originalWidth + tiledAreaWidth, height: image.size.height))

    let leftPart = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    UIGraphicsBeginImageContextWithOptions(CGSize(width: newWidth, height: image.size.height),
                                           false, image.scale)

    let secondResizable = leftPart?.resizableImage(withCapInsets: UIEdgeInsets(top: 0,
                                                                              left: tiledAreaWidth + originalWidth - 3,
                                                                              bottom: 0,
                                                                              right: 0),
                                              resizingMode: .stretch)
    secondResizable?.draw(in: CGRect(x: 0, y: 0, width: newWidth, height: image.size.height))

    let fullImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    return fullImage
}
  • Вам просто нужно предоставить изображение с нужной новой шириной, оно будет делать горизонтальное растяжение для вас.

Ответ 5

Мы можем растянуть изображение, используя приведенный ниже код: Здесь нам нужно, чтобы стрелка знака была в том же размере, чтобы растянуть среднюю часть ниже начала стрелки (предположим, что она будет 2 px)

UIImage *image = [UIImage imageNamed:@"img_loginButton.png"];
    UIEdgeInsets edgeInsets;
    edgeInsets.left = 0.0f;
    edgeInsets.top = 2.0f;
    edgeInsets.right = 0.0f;
    edgeInsets.bottom = 0.0f;
    image = [image resizableImageWithCapInsets:edgeInsets];
//Use this image as your controls image