在iOS 5中自定义UISegmentedControl

时间:2012-02-02 14:37:38

标签: objective-c ios ios5 uisegmentedcontrol

这是我的问题。我通过以下方式设置背景和分隔图像来自定义UISegmentedControl:

[[UISegmentedControl appearance] setDividerImage:segmentUnselectedUnselected forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setDividerImage:segmentSelectedUnselected forLeftSegmentState:UIControlStateSelected rightSegmentState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setDividerImage:segUnselectedSelected forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateSelected barMetrics:UIBarMetricsDefault];

[[UISegmentedControl appearance] setBackgroundImage:segmentUnselected forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setBackgroundImage:segmentSelected forState:UIControlStateSelected barMetrics:UIBarMetricsDefault];

当我尝试在viewDidLoad

中选择第一个分段时
self.segmentedControl.selectedIndex = 1;

我得到以下奇怪的事情:

enter image description here

而不是:

enter image description here

有谁知道这是一个错误,我怎么能提供错误报告?如果没有,我的代码会出现什么问题?

6 个答案:

答案 0 :(得分:10)

在做了一些测试并尝试了几个不同的位置进行自定义之后,我相信这可能确实是一个错误。

即使使用非常简单的直接UISegmentedControl,这也是我得到的(使用Xcode 4.3.1,iOS 5.1):

  

启动并选择代码中的中间元素后:   After launching and selecting the middle element in code

     

用户点击后点击中间元素:   After user-clicked away and clicking back on middle element

我使用3px宽的图像作为分隔符,1px宽的图像作为背景。

修改的: 我想我找到了一个解决方法:尝试排队指令以选择元素,而不是在viewDidLoad中执行它,如下所示:

dispatch_async(dispatch_get_main_queue(),^{
   self.segmentedControl.selectedSegmentIndex = 1;
});

在上面的示例中,排队该指令使其工作正常。

答案 1 :(得分:4)

我认为你的图片CapInsets不正确,请加倍http://www.raywenderlich.com/4344/user-interface-customization-in-ios-5

中的示例

以下是教程中的一些代码,供快速参考:

UIImage *segmentSelected = [[UIImage imageNamed:@"segcontrol_sel.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 15, 0, 15)];
UIImage *segmentUnselected = [[UIImage imageNamed:@"segcontrol_uns.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 15, 0, 15)];
UIImage *segmentSelectedUnselected = [UIImage imageNamed:@"segcontrol_sel-uns.png"];
UIImage *segUnselectedSelected = [UIImage imageNamed:@"segcontrol_uns-sel.png"];
UIImage *segmentUnselectedUnselected = [UIImage imageNamed:@"segcontrol_uns-uns.png"];

[[UISegmentedControl appearance] setBackgroundImage:segmentUnselected forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setBackgroundImage:segmentSelected forState:UIControlStateSelected barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setDividerImage:segmentUnselectedUnselected forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setDividerImage:segmentSelectedUnselected forLeftSegmentState:UIControlStateSelected rightSegmentState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setDividerImage:segUnselectedSelected forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateSelected barMetrics:UIBarMetricsDefault];

答案 2 :(得分:1)

在我做了很多实验之后,我想出了如何解决这个问题。

您的问题来自细分的宽度设置不正确。

第一点 - 我们需要在设置各个段的宽度之前进行UI自定义。

第二点 - 我们需要计算分频器的宽度,这非常重要。当我们进行自定义时,分隔符是UISegmentedControl元素的一部分。分隔符不是叠加层。我们也应该计算分频器的宽度。

第三点 - 当我们对段使用设置宽度方法时,段宽度不需要包括分隔符的宽度。

如果您遵循上述规则,您将获得完美的自定义UISegmentedControl。

答案 3 :(得分:1)

您是否尝试过设置可调整大小的图片?

例如:

UIImage *segmentSelected = [[UIImage imageNamed:@"SegmentSelectedImage"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 5, 0, 5)];
[[UISegmentedControl appearance] setBackgroundImage:segmentSelected forState:UIControlStateSelected barMetrics:UIBarMetricsDefault];

答案 4 :(得分:0)

您可能希望在viewDidLoad之前尝试初始化外观设置。在演示中我已经看到这通常在application:didFinishLaunchingWithOptions:中完成,尽管在加载包含自定义视图的笔尖之前的任何点都应该有效。

答案 5 :(得分:0)

我有同样的问题并以不同的方式解决了它。我只是评论了这行代码:

self.pageController.segmentedControlStyle = UISegmentedControlStyleBar;

段栏将视图更改为正常状态。