ios 自定义左右 UISegmentedControl 按钮

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10562300/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 18:20:56  来源:igfitidea点击:

Customizing Left & Right UISegmentedControl Buttons

iphoneiosios5uisegmentedcontroluiappearance

提问by Year3000

I'm trying to customize the following segmented control, using a left image for the first button and a right image for the second button. How would I do this using UIAppearance?

我正在尝试自定义以下分段控件,为第一个按钮使用左图,为第二个按钮使用右图。我将如何使用 UIAppearance 做到这一点?

I want to change the following segmentedControl:

我想更改以下分段控件:

enter image description here

在此处输入图片说明

to something similar like below:

类似于以下内容:

enter image description here

在此处输入图片说明

The reason I want to use a custom image is so that I can change the corners of the buttons. If you look at the blue segmented control, it's more squared (my image has it's own corners).

我想使用自定义图像的原因是我可以更改按钮的角。如果您查看蓝色分段控件,它会更加方形(我的图像有自己的角)。

I was thinking of something like this but no use:

我在想这样的事情,但没有用:

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];

回答by Maurizio

You need to provide the following images:

您需要提供以下图片:

  • segment background selected (this has both left and right caps)
    enter image description here
  • segment background unselected (this has both left and right caps)
    enter image description here
  • segment middle, left selected, right unselected
    enter image description here
  • segment middle, left unselected, right selected
    enter image description here
  • segment middle, both left & right selected
    enter image description here
  • segment middle, both left & right unselected
    enter image description here
  • 选择了段背景(这有左右大写)
    在此处输入图片说明
  • 未选择段背景(这有左右大写)
    在此处输入图片说明
  • 段中间,左选中,右未选中
    在此处输入图片说明
  • 段中间,左未选择,右选择
    在此处输入图片说明
  • 段中间,左右选择
    在此处输入图片说明
  • 段中间,左右都未选择
    在此处输入图片说明

And then use the following code to set:

然后使用以下代码进行设置:

/* 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];

Note that you'll have to adjust the cap size in the stretchable images to match your images.

请注意,您必须调整可拉伸图像中的帽尺寸以匹配您的图像。

回答by iwasrobbed

Maurizio's answer didn't quite work for me with a segmented control within a toolbar; it kept showing these phantom lines on the controls since the divider images weren't wide enough.

Maurizio 的回答对我来说对工具栏中的分段控件不太适用;由于分隔图像不够宽,它一直在控件上显示这些幻影线。

So I made my own. Here are all of the images you will need for Xcode and I also put in the Photoshop files for creating the segmented control images so you can change the styling:

所以我自己做了。以下是 Xcode 所需的所有图像,我还放入了 Photoshop 文件以创建分段控制图像,以便您可以更改样式:

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

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

Put this in your AppDelegate to have it change the appearance, using the attached images, of all segmented controls within a toolbar:

把它放在你的 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];
}

回答by Amy Worrall

You need to make one background image that is for all your segments, and also an image that is just the left edge of a button, an image that is the join between two buttons, and an image that is the right edge. Some of those need to be done for multiple states. So here is your image list:

您需要制作一个适用于所有片段的背景图像,以及一个位于按钮左边缘的图像、一个作为两个按钮之间连接的图像以及一个作为右边缘的图像。其中一些需要为多个状态完成。所以这是你的图像列表:

  • left cap, selected
  • left cap, unselected
  • segment background, selected
  • segment background, unselected
  • right cap, selected
  • right cap, unselected
  • middle cap, left selected right unselected
  • middle cap, left unselected, right selected
  • middle cap, both selected
  • middle cap, both unselected
  • 左帽,选中
  • 左帽,未选中
  • 段背景,已选择
  • 段背景,未选中
  • 右帽,选中
  • 右帽,未选中
  • 中间大写,左选中右未选中
  • 中盖,左未选中,右选中
  • 中盖,均已选中
  • 中盖,均未选中

For the middle caps you can put them in like this: (text from Apple docs).

对于中大写字母,您可以像这样放置它们:(来自 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];

If you're using UIAppearance, obviously you'd send those messages to the appearance proxy.

如果您正在使用UIAppearance,显然您会将这些消息发送到外观代理。