在iOS 5中自定义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]; 

当我尝试在viewDidLoadselect第一个分段

 self.segmentedControl.selectedIndex = 1; 

我得到以下奇怪的事情:

在这里输入图像说明

代替:

在这里输入图像说明

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

经过一些testing,并尝试几个不同的位置进行定制,我相信这可能确实是一个错误。

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

启动并select代码中的中间元素之后: 启动并选择代码中的中间元素后

用户点击后点击中间元素: 用户点击后点击中间元素

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

编辑 :我想我find了一个解决方法:尝试排队指令select元素,而不是在viewDidLoad中执行它,如下所示:

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

在我上面的例子中,排队该指令使其工作得很好。

我认为您的图片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]; 

在做了大量的实验后,我想出了如何解决这个问题。

您的问题是从段的不正确的宽度设置。

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

第二点 – 我们需要计算分频器的宽度,这非常重要。 当我们进行定制时,分隔线是UISegmentedControl元素的一部分。 分隔线不是覆盖层。 我们也应该计算分频器的宽度。

第三点 – 当我们为段设置宽度方法时,段宽不需要包含分隔线的宽度。

如果你遵循上面的规则,你会得到一个完美的定制的UISegmentedControl。

你有没有尝试设置可resize的图像?

例如:

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

您可能想尝试初始化您的外观设置比viewDidLoad更早。 在演示中,我已经看到这通常是在application:didFinishLaunchingWithOptions:完成的application:didFinishLaunchingWithOptions:但在加载包含自定义视图的笔尖之前的任何一点都应该工作。

我有同样的问题,并以不同的方式解决。 我刚刚评论了这一行代码:

 self.pageController.segmentedControlStyle = UISegmentedControlStyleBar; 

而细分条将其视图更改为正常状态。