Настройка левой и правой кнопок UISegmentedControl

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

Я хочу изменить следующий segmentedControl:

введите здесь описание изображения

на что-то похожее, как показано ниже:

введите здесь описание изображения

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

Я думал о чем-то подобном, но бесполезно:

UIImage *leftImage = [[UIImage imageNamed:@"leftControl.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 15, 0, 15)];
UIImage *rightImage = [[UIImage imageNamed:@"rightControl.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 15, 0, 15)];

[[UISegmentedControl appearance] setBackgroundImage:leftImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault ];
[[UISegmentedControl appearance] setBackgroundImage:rightImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];

person Year3000    schedule 12.05.2012    source источник
comment
Я собрал несколько изображений (включая файлы Photoshop) и код здесь: stackoverflow.com/a/16819218/308315   -  person iwasrobbed    schedule 29.05.2013


Ответы (3)


Вам необходимо предоставить следующие изображения:

  • выбран фон сегмента (у него есть как левая, так и правая заглавные буквы)
    введите здесь описание изображения
  • фон сегмента не выбран (у него есть как левая, так и правая заглавные буквы)
    введите здесь описание изображения
  • средний сегмент, левый выделен, правый не выбран
    введите здесь описание изображения
  • средний сегмент, слева невыбрано, справа выбрано
    введите здесь описание изображения
  • средний сегмент, выбраны левый и правый
    введите здесь описание изображения
  • средний сегмент, левый и правый не выбраны
    введите здесь описание изображения

А затем используйте следующий код для установки:

/* Unselected background */
UIImage *unselectedBackgroundImage = [[UIImage imageNamed:@"segment_background_unselected"] resizableImageWithCapInsets:UIEdgeInsetsMake(10, 10, 10, 10)];
[[UISegmentedControl appearance] setBackgroundImage:unselectedBackgroundImage
                                           forState:UIControlStateNormal
                                         barMetrics:UIBarMetricsDefault];

/* Selected background */
UIImage *selectedBackgroundImage = [[UIImage imageNamed:@"segment_background_selected"] resizableImageWithCapInsets:UIEdgeInsetsMake(10, 10, 10, 10)];
[[UISegmentedControl appearance] setBackgroundImage:selectedBackgroundImage
                                           forState:UIControlStateSelected
                                         barMetrics:UIBarMetricsDefault];

/* Image between two unselected segments */
UIImage *bothUnselectedImage = [[UIImage imageNamed:@"segment_middle_unselected"] resizableImageWithCapInsets:UIEdgeInsetsMake(15, 0, 15, 0)];
[[UISegmentedControl appearance] setDividerImage:bothUnselectedImage
                             forLeftSegmentState:UIControlStateNormal
                               rightSegmentState:UIControlStateNormal
                                      barMetrics:UIBarMetricsDefault];

/* Image between segment selected on the left and unselected on the right */
UIImage *leftSelectedImage = [[UIImage imageNamed:@"segment_middle_left_selected"] resizableImageWithCapInsets:UIEdgeInsetsMake(15, 0, 15, 0)];
[[UISegmentedControl appearance] setDividerImage:leftSelectedImage
                             forLeftSegmentState:UIControlStateSelected
                               rightSegmentState:UIControlStateNormal
                                      barMetrics:UIBarMetricsDefault];

/* Image between segment selected on the right and unselected on the left */
UIImage *rightSelectedImage = [[UIImage imageNamed:@"segment_middle_right_selected"] resizableImageWithCapInsets:UIEdgeInsetsMake(15, 0, 15, 0)];
[[UISegmentedControl appearance] setDividerImage:rightSelectedImage
                             forLeftSegmentState:UIControlStateNormal
                               rightSegmentState:UIControlStateSelected
                                      barMetrics:UIBarMetricsDefault];

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

person Maurizio    schedule 05.09.2012
comment
Да, спасибо, изображения сэкономили много времени и исследований, очень признательны - person Tom DeMille; 25.02.2013
comment
Учитывая изображения, описанные выше, вам нужно предоставить эквивалент HD (например, @ 2x.png) или метод resizableImageWithCapInsets: по существу справляется с этим для нас? - person avelis; 03.04.2013
comment
@avelis да, вы должны предоставить изображения как 1x, так и 2x. - person Maurizio; 03.04.2013
comment
@avelis Как всегда, вы указываете имя стандартного образа image.png, а затем ОС позаботится о замене его на [email protected], если это необходимо. - person iwasrobbed; 29.05.2013
comment
Очень хорошо! Пара вещей. Похоже, вы забыли установить середину для случая, когда выбраны оба сегмента. Кроме того, вы также можете установить атрибуты заголовка, если хотите настроить шрифт/цвета/тени/и т. д. [[Внешний вид UISegmentedControl] setTitleTextAttributes:...]. - person Craig B; 02.06.2013
comment
Привет @iWasRobbed, я хочу иметь разные изображения для нажатого и ненажатого состояния, а также изображения будут разными для каждого сегмента. Можем ли мы добиться этого, используя приведенный выше код. - person Ranjit; 26.06.2013

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

Поэтому я сделал свой собственный. Вот все изображения, которые вам понадобятся для Xcode, и я также добавил файлы Photoshop для создания сегментированных контрольных изображений, чтобы вы могли изменить стиль:

https://s3.amazonaws.com/iwasrobbed/stackoverflow/Custom+Segmented+Control.zip

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

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [self customizeAppAppearance];
}

- (void)customizeAppAppearance
{
    // Toolbar
    [[UIToolbar appearance] setBackgroundImage:[[UIImage imageNamed:@"toolbar.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(22, 5, 22, 5)] forToolbarPosition:UIToolbarPositionAny barMetrics:UIBarMetricsDefault];

    // Segmented Controls within Toolbars

    // Unselected background
    UIImage *unselectedBackgroundImage = [[UIImage imageNamed:@"segmentInactive.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(15, 15, 15, 15)];
    [[UISegmentedControl appearanceWhenContainedIn:[UIToolbar class], nil] setBackgroundImage:unselectedBackgroundImage
                                                                                     forState:UIControlStateNormal
                                                                                   barMetrics:UIBarMetricsDefault];

    // Selected background
    UIImage *selectedBackgroundImage = [[UIImage imageNamed:@"segmentActive.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(15, 15, 15, 15)];
    [[UISegmentedControl appearanceWhenContainedIn:[UIToolbar class], nil] setBackgroundImage:selectedBackgroundImage
                                                                                     forState:UIControlStateSelected
                                                                                   barMetrics:UIBarMetricsDefault];

    // Image between two unselected segments
    UIImage *bothUnselectedImage = [[UIImage imageNamed:@"segmentBothInactive.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(15, 10, 15, 10)];
    [[UISegmentedControl appearanceWhenContainedIn:[UIToolbar class], nil] setDividerImage:bothUnselectedImage
                                                                       forLeftSegmentState:UIControlStateNormal
                                                                         rightSegmentState:UIControlStateNormal
                                                                                barMetrics:UIBarMetricsDefault];

    // Image between segment selected on the left and unselected on the right
    UIImage *leftSelectedImage = [[UIImage imageNamed:@"segmentLeftActiveRightInactive.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(15, 0, 15, 0)];
    [[UISegmentedControl appearanceWhenContainedIn:[UIToolbar class], nil] setDividerImage:leftSelectedImage
                                                                       forLeftSegmentState:UIControlStateSelected
                                                                         rightSegmentState:UIControlStateNormal
                                                                                barMetrics:UIBarMetricsDefault];

    // Image between segment selected on the right and unselected on the left
    UIImage *rightSelectedImage = [[UIImage imageNamed:@"segmentRightActiveLeftInactive.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(15, 0, 15, 0)];
    [[UISegmentedControl appearanceWhenContainedIn:[UIToolbar class], nil] setDividerImage:rightSelectedImage
                                                                       forLeftSegmentState:UIControlStateNormal
                                                                         rightSegmentState:UIControlStateSelected
                                                                                barMetrics:UIBarMetricsDefault];
}
person iwasrobbed    schedule 29.05.2013

Вам нужно создать одно фоновое изображение для всех ваших сегментов, а также изображение, представляющее собой левый край кнопки, изображение, представляющее собой соединение между двумя кнопками, и изображение, являющееся правым краем. Некоторые из них должны быть выполнены для нескольких состояний. Итак, вот ваш список изображений:

  • левая крышка, выбранная
  • левая кепка, невыбрано
  • фон сегмента, выбран
  • фон сегмента, невыбранный
  • правая крышка, выбранная
  • правая крышка, невыбранный
  • средняя заглавная, левая выбрана, правая не выбрана
  • средняя заглавная, левая не выбрана, правая выбрана
  • средняя крышка, обе выбраны
  • средняя крышка, обе невыбранные

Для средних заглавных букв вы можете вставить их так: (текст из документации Apple).

// Image between two unselected segments.
[mySegmentedControl setDividerImage:image1 forLeftSegmentState:UIControlStateNormal
              rightSegmentState:UIControlStateNormal barMetrics:barMetrics];
// Image between segment selected on the left and unselected on the right.
[mySegmentedControl setDividerImage:image1 forLeftSegmentState:UIControlStateSelected
              rightSegmentState:UIControlStateNormal barMetrics:barMetrics];
// Image between segment selected on the right and unselected on the right.
[mySegmentedControl setDividerImage:image1 forLeftSegmentState:UIControlStateNormal
              rightSegmentState:UIControlStateSelected barMetrics:barMetrics];

Если вы используете UIAppearance, очевидно, вы должны отправлять эти сообщения прокси-серверу внешнего вида.

person Amy Worrall    schedule 12.05.2012
comment
Каково точное соответствие между приведенным выше списком изображений и вызовами для установки фоновых/разделительных изображений прокси-сервера управления/внешнего вида? - person Thom; 22.08.2012