在 iOS 5 中自定义 UISegmentedControl
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9114186/
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
Customizing UISegmentedControl in iOS 5
提问by nimeshdesai
Here is my problem. I am customizing a UISegmentedControl by setting the background and divider images in the following way:
这是我的问题。我通过以下方式设置背景和分隔图像来自定义 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];
When I try to make the 1st segmented selected within viewDidLoad
当我尝试在其中选择第一个分段时 viewDidLoad
self.segmentedControl.selectedIndex = 1;
I get the following weird thing:
我得到以下奇怪的事情:
instead of:
代替:
Does anyone know if this is a bug and how could I provide a bug report? If not, what could be wrong with my code?
有谁知道这是否是一个错误,我该如何提供错误报告?如果没有,我的代码可能有什么问题?
采纳答案by Fernando Madruga
After doing some tests and trying several different locations for the customization, I believe this may indeed be a bug.
在做了一些测试并尝试了几个不同的自定义位置之后,我相信这确实可能是一个错误。
Even with a very simple straight UISegmentedControl, this is what I get (using Xcode 4.3.1, iOS 5.1):
即使使用非常简单的直接 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:
启动并选择代码中的中间元素后:
在用户单击离开并单击中间元素后:
I used 3px wide images for the separators and 1px wide images for the backgrounds.
我使用 3px 宽的图像作为分隔符,使用 1px 宽的图像作为背景。
Edit: I think I found a workaround: try queueing the instruction to select the element, rather than executing it in viewDidLoad, like this:
编辑:我想我找到了一种解决方法:尝试将指令排队以选择元素,而不是在 viewDidLoad 中执行它,如下所示:
dispatch_async(dispatch_get_main_queue(),^{
self.segmentedControl.selectedSegmentIndex = 1;
});
On my example above, queuing that instruction makes it work just fine.
在我上面的示例中,将该指令排队使其工作得很好。
回答by flypig
I think your image CapInsets is incorrect, please double the example in http://www.raywenderlich.com/4344/user-interface-customization-in-ios-5
我认为您的图像 CapInsets 不正确,请将http://www.raywenderlich.com/4344/user-interface-customization-in-ios-5 中的示例加倍
here is some codes from the Tutorial for quick reference:
以下是教程中的一些代码以供快速参考:
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];
回答by user403015
I figured out how to solve the problem after I did a lot of experiments.
经过大量的实验,我想出了如何解决这个问题。
Your problem is from the incorrect width setting for the segments.
您的问题是由于段的宽度设置不正确。
First point - we need to do UI customization before setting the width of individual segments.
第一点 - 我们需要在设置单个段的宽度之前进行 UI 自定义。
Second point - we need to count the width of the divider(s) and it is very important. When we do customization, the divider(s) is part of the UISegmentedControl elements. The divider is not an overlay. We should count the width of the divider also.
第二点 - 我们需要计算分隔线的宽度,这非常重要。当我们进行自定义时,分隔符是 UISegmentedControl 元素的一部分。分隔线不是叠加层。我们还应该计算分隔线的宽度。
Third point - when we use the set width method for the segments, the segment width does not need to include the divider's width.
第三点 - 当我们对段使用设置宽度方法时,段宽度不需要包括分隔线的宽度。
If you follow the above rules, you would get a perfect customized UISegmentedControl.
如果你遵循以上规则,你将得到一个完美的自定义 UISegmentedControl。
回答by Julien
Have you tried to set resizable images?
您是否尝试过设置可调整大小的图像?
For example:
例如:
UIImage *segmentSelected = [[UIImage imageNamed:@"SegmentSelectedImage"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 5, 0, 5)];
[[UISegmentedControl appearance] setBackgroundImage:segmentSelected forState:UIControlStateSelected barMetrics:UIBarMetricsDefault];
回答by Casey Fleser
You may want to try initializing your appearance settings earlier than viewDidLoad
. In the demonstrations I've seen this was usually done in application:didFinishLaunchingWithOptions:
, though any point prior to loading the nib containing the customized views should work.
您可能想尝试在 之前初始化您的外观设置viewDidLoad
。在我看到的演示中application:didFinishLaunchingWithOptions:
,这通常是在 中完成的,尽管在加载包含自定义视图的笔尖之前的任何一点都应该起作用。
回答by Wert1go
I had the same problem and solved it by different way. I just commented this line of code:
我遇到了同样的问题,并以不同的方式解决了它。我刚刚评论了这行代码:
self.pageController.segmentedControlStyle = UISegmentedControlStyleBar;
And segment bar changed it view to normal state.
段栏将其视图更改为正常状态。