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

Как предотвратить растягивание фонового изображения кнопки?

Я выделяю UIButtonTypeCustom UIButton для UIView с фоновым изображением, которое меньше, чем рамка кнопки. Причина, по которой изображение меньше, заключается в том, что я пытаюсь добавить больше "целевой области" для UIButton. Однако изображение масштабируется до полного размера кадра, а не только размером изображения.

Я попытался установить для свойства UIButton и UIButton imageView contentMode значение "UIViewContentModeScaleAspectFit", но не удача, изображение все равно растягивается.

Есть ли способ сделать то, что я пытаюсь сделать программно?

Спасибо заранее!

4b9b3361

Ответ 1

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

A UIButton имеет два типа изображений, которые он может отображать - изображение переднего плана и фоновое изображение. Предполагается, что фоновое изображение для кнопки заменит текстуру фона кнопки. Таким образом, имеет смысл, что он растягивается, чтобы заполнить весь фон. Однако изображение переднего плана кнопки должно быть значком, который может отображаться рядом с текстом или не отображаться; он не будет растягиваться. Он может сокращаться, если кадр меньше изображения, но он не растягивается. Вы даже можете установить выравнивание изображения переднего плана с помощью свойств выравнивания управления в Interface Builder.

Кнопка переднего плана и фоновое изображение могут быть установлены в коде следующим образом:

// stretchy
[self setBackgroundImage:backgroundImage forState:UIControlStateNormal];  

// not stretchy
[self setImage:forgroundImage forState:UIControlStateNormal]; 

Ответ 2

У вас нет доступа к фону imageView, , но есть полностью работающий обходной путь:

РЕДАКТИРОВАТЬ: есть еще лучшее обходное решение, чем то, что я опубликовал изначально. Вы можете создать UIImage из любого цвета и вызвать -setBackgroundImage:forState.

См. bradley's ответ, здесь: fooobar.com/questions/119117/...


Оригинальный ответ:

Вместо вызова -setBackgroundImage:forState: создайте новый UIImageView и добавьте его как подпункт кнопки.

UIImageView *bgImageView = [[UIImageView alloc] initWithImage:img];
bgImageView.contentMode = UIViewContentModeScaleAspectFit;
[bgImageView setFrame:CGRectMake(0, 0, videoButton.frame.size.width, videoButton.frame.size.height)];
bgImageView.tag = 99;
[yourButton addSubview:bgImageView];
[yourButton bringSubviewToFront:yourButton.imageView];
  • Создание образа
  • Установите режим содержимого и фрейм
  • Я также устанавливаю распознаваемый тег, так что, когда экран вращается, я могу легко найти свой собственный образ в представлении кнопок и reset его кадр
  • Добавьте его как подпункт к кнопке
  • Приведите фронтальное изображениеПримечание кнопки на передней панели, чтобы наш пользовательский образ не перекрывал его.

Когда нужно поворачивать кнопку, просто найдите изображениеView по его тегу и reset его кадр:

UIImageView *bgImageView = (UIImageView *)[button viewWithTag:99];
[bgImageView setFrame:CGRectMake(0, 0, newWidth, newHeight)];

Ответ 3

Самый чистый и простой способ, вероятно, использовать вставки названия кнопки.

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

myButton.titleEdgeInsets = UIEdgeInsetsMake(0, -myImage.width, 0, 0)

Это переместит текст обратно туда, где он был до того, как изображение было добавлено слева. Вы также можете использовать это значение, чтобы добавить кнопку добавления к вам.

Ответ 4

Еще одно соображение - ограничение BaseLine. Если на ваших кнопках установлено это ограничение (отображается как горизонтальная или вертикальная линия с помощью нескольких элементов управления на вашем макете), это приведет к тому, что ваши изображения будут растягиваться, не растягивая базовое управление кнопками. Если ваша кнопка в противном случае должным образом ограничена (ведущие/конечные и верхние/нижние пробелы и т.д.), Удаление ограничения BaseLine не должно влиять на макет, позволяя правильному изображению переднего плана масштабировать основную форму кнопки.

Ответ 5

Я думаю, самым простым решением является использование метода UIImage resizableImageWithCapInsets. Используйте UIEdgeInsetsMake для настройки свободных пробелов.

Ответ 6

Наткнулся на эту проблему.

Добавление изображения программно, как подробно объяснили меммоны, не помогло:(

У меня была кнопка 100x40 и изображение 100x100, она выглядела бы сжатой, а не установленной, так как можно было бы сделать вывод из опции "Aspect Fit". Фактически, не те варианты просмотра имели эффект.

Мне просто пришлось перемасштабировать его, чтобы он поместился на кнопке, а затем используйте setImage:

UIImage *img=[UIImage imageNamed:@"myimage.png"];
CGImageRef imgRef = [img CGImage];
CGFloat imgW = CGImageGetWidth(imgRef);
CGFloat imgH = CGImageGetHeight(imgRef);
CGFloat btnW = myBttn.frame.size.width;
CGFloat btnH = myBttn.frame.size.height;
//get lesser button dimension
CGFloat minBtn=btnW;
if (btnW>btnH) {
    minBtn=btnH;
}
//calculate scale using greater image dimension
CGFloat scl=imgH/minBtn;
if (imgW>imgH) {
    scl=imgW/minBtn;
}
//scale image
UIImage *scaledImage = [UIImage imageWithCGImage:[img CGImage] scale:(img.scale * scl) orientation:(img.imageOrientation)];
//clean up
UIGraphicsEndImageContext();
//set it on a button
[myBttn setImage:scaledImage forState:UIControlStateNormal];

Ответ 7

Это просто:

    ImageBn.imageView?.contentMode = .scaleAspectFit
    ImageBn.setImage(chosenImage, for: .normal)

Ответ 8

Answerbot отвечает на вопрос, что правильно и правильно делать. Не сражайтесь с ОС и не используйте вещи по назначению, это всегда хороший совет. Однако иногда вам нужно нарушать правила.

Мне удалось замаскировать увеличенное фоновое изображение (не мешать ему), наложив его на черный CAlayer, а затем снова наложив его с помощью правильно настроенного изображения CAlayer. Все это было сделано путем создания подкласса UIButton и перезаписи метода setHighlighted.

НУЖЕН КОД:

- (void)setHighlighted:(BOOL)highlighted
{
super.highlighted = highlighted;

//
//Whenever an image needs to be highlighted, create a dimmed new image that is correctly       sized. Below it is a englarged stretched image.
//
if (highlighted != _previousHighlightedSate)
{
    _previousHighlightedSate = highlighted;

    if (highlighted)
    {
        //Create a black layer so image can dim
        _blackLayer = [CALayer layer];
        _blackLayer.bounds = self.bounds;
        CGRect rect = _blackLayer.bounds;
        rect.size.width = rect.size.width*2;
        rect.size.height = rect.size.height*2;
        _blackLayer.bounds = rect;
        _blackLayer.backgroundColor = [[UIColor blackColor] CGColor];

        //create image layer
        _nonStretchImageLayer = [CALayer layer];
        _nonStretchImageLayer.backgroundColor = [UIColor blackColor].CGColor;
        _nonStretchImageLayer.bounds = CGRectMake(0  , 0, self.bounds.size.width, self.bounds.size.height);
        _nonStretchImageLayer.frame = CGRectMake(0  , 0, self.bounds.size.width, self.bounds.size.height);
        _nonStretchImageLayer.contentsGravity = kCAGravityResizeAspect;//default is to resize
        _nonStretchImageLayer.contents = (id)self.imageView.image.CGImage;
        _nonStretchImageLayer.opacity = 0.5;

        //add layers to image view
        [self.imageView.layer addSublayer:_blackLayer];
        [self.imageView.layer addSublayer:_nonStretchImageLayer];
    }
    else
    {
        //remove from image view
        [_blackLayer removeFromSuperlayer];
        [_nonStretchImageLayer removeFromSuperlayer];

        //nil them out.
        _blackLayer = nil;
        _nonStretchImageLayer = nil;
    }
}  

Вдохновение для этой работы произошло от здесь

Ответ 9

Что вам нужно сделать, это добавить изображение как UIImageView.

Затем добавьте кнопку с прозрачным фоном (UIColor ClearColor) поверх нее с нужной шириной и высотой.