【问题标题】:Customizing Left & Right UISegmentedControl Buttons自定义左右 UISegmentedControl 按钮
【发布时间】:2013-05-30 00:24:01
【问题描述】:

我正在尝试自定义以下分段控件,对第一个按钮使用左图像,对第二个按钮使用右图像。我将如何使用 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];

【问题讨论】:

标签: iphone ios ios5 uisegmentedcontrol uiappearance


【解决方案1】:

您需要提供以下图片:

  • 已选择段背景(这有左右大写)
  • 未选择段背景(这有左右大写)
  • 中间段,左侧选中,右侧未选中
  • 中间段,左侧未选中,右侧选中
  • 中间段,左右都选中
  • 中间段,左右均未选中

然后用下面的代码来设置:

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

请注意,您必须调整可拉伸图像中的大写大小以匹配您的图像。

【讨论】:

  • 是的,谢谢,这些图片节省了大量时间和研究,非常感谢
  • 考虑到上述图像,您是否需要提供等效的高清图像(即@2x.png)或resizableImageWithCapInsets: 方法基本上为我们处理?
  • @avelis 是的,您必须同时提供 1x 和 2x 图像。
  • @avelis 与往常一样,您指定标准image.png 图像的名称,然后操作系统会在必要时将其换成image@2x.png
  • 非常好!夫妇的事情。看起来您忘记为选择两个段的情况设置中间值。此外,如果您想要自定义字体/颜色/阴影/等 [[UISegmentedControl 外观] setTitleTextAttributes:...],您也可以设置标题属性。
【解决方案2】:

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

所以我自己做了。以下是 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];
}

【讨论】:

    【解决方案3】:

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

    • 左帽,已选择
    • 左帽,未选中
    • 段背景,已选择
    • 段背景,未选中
    • 右帽,已选择
    • 右帽,未选中
    • 中帽,左选中右未选中
    • 中帽,左侧未选中,右侧已选中
    • 中间帽,均已选择
    • 中间帽,均未选中

    对于中间大写字母,您可以这样输入:(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,显然您会将这些消息发送到外观代理。

    【讨论】:

    • 以上图像列表与设置控件/外观代理的背景/分隔图像的调用之间的确切映射是什么?
    猜你喜欢
    • 2019-08-03
    • 2012-12-09
    • 2010-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-19
    相关资源
    最近更新 更多