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

Использование растягиваемых изображений в раскадках Xcode

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

Возможно ли это сделать непосредственно в раскадках без написания кода? Мне очень нравится возможность использовать раскадровки для всех графических материалов и сохранить код в чистоте от материалов UI, но мне кажется, что я не могу уйти от него здесь.

Если это невозможно, что бы вы предложили иначе?

4b9b3361

Ответ 1

Обновление для iOS 7 +
iOS 7+ теперь поддерживает растягивающиеся изображения из каталога активов. Используя каталог активов, вы можете указать, как нарезать изображения и как они масштабируются (растягивать или черепицей). Эти атрибуты каталога каталога для изображения будут немедленно отображены в раскадровке. Отличное новое усовершенствование. Для получения дополнительной информации см. Документы Apple в Каталоге активов

Для развертывания в версиях iOS до 7:
Это малоизвестный факт, но вы можете абсолютно установить надписи на крышке изображения, используя только Interface Builder/Storyboard и свойства растяжения в инспекторе атрибутов. Спасибо Victor за оригинальный ответ.

Рассматривая свойства растяжения в инспекторе атрибутов UIImage, значения X и Y являются позициями для начальной точки растяжения относительно всей ширины и высоты изображения. Значение 0.5 означает точку в середине изображения.

Ширина и высота - это размеры для растяжимой области относительно размера изображения. Таким образом, установка ширины в значение 1/imageWidth установила бы растягиваемую область шириной 1px.

Большинство растягиваемых изображений будут растягиваться из середины, поэтому использование этих значений для X, Y, Ширина и Высота обычно будет работать:

X = 0.5
Y = 0.5
Width = 1/imageWidth
Height = 1/imageHeight

Примечание. Если у вас очень маленькое изображение, которое вы растягиваете, это означает, что свойства ширины и высоты будут очень малы (например, 0,008) и 0.0 могут использоваться вместо этого. Таким образом, практически говоря, 0.5, 0.5, 0.0, 0.0 почти всегда будут работать для X, Y, Width и Height.

В небольшом числе случаев, когда 0.0 не работает для Width и Height, это означает, что вам нужно использовать калькулятор для установки этих значений в IB. Тем не менее, я думаю, что это обычно предпочтительнее, чем устанавливать его программно, так как вы сможете увидеть полученное растянутое изображение в IB (WYSIWYG).

Stretchable image attributes

Обновление:. Некоторые люди указали, что, хотя растягивающие изображения работают в Storyboard, используя приведенные выше предложения, растягивание изображений на кнопках все еще прерывается, даже с iOS7. Чтобы не волноваться, это легко решить, создав категорию UIButton, которая позаботится о настройке вложенных надписей для состояний управления:

@implementation UIButton (Stretchable)

/* Automatically set cap insets for the background image. This assumes that
   the image is a standard slice size with a 1 px stretchable interior */
- (void)setBackgroundImageStretchableForState:(UIControlState)controlState
{
    UIImage *image = [self backgroundImageForState:controlState];
    if (image)
    {
       CGFloat capWidth =  floorf(image.size.width / 2);
       CGFloat capHeight =  floorf(image.size.height / 2);
       UIImage *capImage = [image resizableImageWithCapInsets:
                     UIEdgeInsetsMake(capHeight, capWidth, capHeight, capWidth)];

       [self setBackgroundImage:capImage forState:controlState];
    }
}

С помощью этой категории вы можете установить растягиваемое изображение для своей кнопки с помощью раскадровки, а затем легко убедиться, что она правильно растягивается, вызывая -setBackgroundImageStretchableForState: в -viewDidLoad. Итерация через иерархию просмотров делает тривиальным сделать это даже для большого количества кнопок в вашем представлении:

NSPredicate *predicate = 
    [NSPredicate predicateWithFormat:@"self isKindOfClass:%@",[UIButton class]];
NSArray *buttons = [self.view.subviews filteredArrayUsingPredicate:predicate];
for (UIButton *button in buttons)
   [button setBackgroundImageStretchableForState:UIControlStateNormal];

Хотя это не так хорошо, как наличие подкласса UIButton, который делает это автоматически для вас (подклассификация UIButton нецелесообразна, так как это кластер классов), это дает вам почти такую ​​же функциональность, как и просто немного кода шаблона в вашем представленииDidLoad - вы можете установить все ваши изображения кнопок в Storyboard и все равно заставить их правильно растягиваться.

Ответ 2

С помощью Xcode 6 (и iOS7 +) вы можете использовать редактор среза при работе с объектами изображений. Переключить режим нарезки с помощью меню Редактор → Показать slicing или нажать кнопку Показать slicing, когда вы выбираете конкретное изображение с помощью редактора (показано ниже).

Show Slicing button

Затем вы можете выбрать изображение для определенной шкалы отображения и правил перетаскивания или отредактировать значения вставки вручную.

Rules

После этого вы можете выбрать это изображение в Interface Builder. Например, я использую его для UIButton Фонового изображения (представление кнопки IB может выглядеть плохо, но при запуске должно быть хорошо).

Мои кнопки выглядят хорошо (работает iOS 7.1 и iOS 8).

enter image description here

Эта ссылка Apple doc

Ответ 3

Это возможно в XCode 5.0 Interface Builder с каталогом активов. Создайте объект изображения (если у вас еще нет каталога активов, вы можете создать его следующим образом:

  • FileNewFileResourcesAsset Catalog
  • Затем EditorNew Image Set
  • Установите изображения для каждого Idiom и Scale
  • Затем нажмите кнопку Show Slicing, чтобы установить фрагменты по вашему желанию.

Проверьте документы Apple здесь: Разработчик Apple: Справка по каталогу активов Затем все, что вам нужно сделать, - установить фоновое изображение кнопки в качестве запрошенного актива.

EDIT: Я забыл упомянуть, что он работает по желанию только в iOS7

Ответ 4

Вот что я сделал: Я установил розетку для кнопки и подключил ее, а затем сделал это в viewDidLoad:

[self.someButton setBackgroundImage:[[self.someButton backgroundImageForState:UIControlStateNormal] resizableImageWithCapInsets:UIEdgeInsetsMake(3, 3, 4, 3)] forState:UIControlStateNormal];

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

Для представления, которое имело много из этих вещей, я сделал это:

for (UIView * subview in self.view.subviews) {
        if ([subview isKindOfClass:[UIImageView class]] && subview.tag == 10) {
            UIImageView* textFieldImageBackground = (UIImageView*)subview;
            textFieldImageBackground.image = [textFieldImageBackground.image stretchableImageWithLeftCapWidth:7 topCapHeight:5];
        } else if([subview isKindOfClass:[UIButton  class]] && subview.tag == 11) {
            UIButton * button = (UIButton*)subview;
            [button setBackgroundImage:[[button backgroundImageForState:UIControlStateNormal] resizableImageWithCapInsets:UIEdgeInsetsMake(3, 3, 4, 3)] forState:UIControlStateNormal];
        }
    }

Обратите внимание, что я установил теги для всех тех, которые я хотел растянуть.

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

Ответ 5

Используйте функцию Xcode Slicing, чтобы указать размеры изменяемой по размеру центральной области изображения и, при необходимости, указать конечные колпачки, которые являются областями изображения, которые не должны заполняться изменяемой площадью. См. О каталогах активов