使用 UISegmentedControl 作为按钮

Posted

技术标签:

【中文标题】使用 UISegmentedControl 作为按钮【英文标题】:Using UISegmentedControl as button 【发布时间】:2010-07-16 11:29:08 【问题描述】:

在我的代码中,我使用UISegmentedControl 作为“按钮”,只有一个段,momentary 属性设置为YES。在 ios 4 之前的 SDK 版本中,这不是问题,但现在 iOS 4 似乎要求至少有 2 个段。以下代码抛出异常:

NSArray *titles = [NSArray arrayWithObject:@"Button Title"];
myButton = [[UISegmentedControl alloc] initWithItems:titles];

现在在 Interface Builder 中,您甚至无法创建少于 2 个段的 UISegmentedControl。它在构建时记录以下错误:

“分段控件的段数属性必须大于等于2。”

我有点难过。有什么解决方法吗?我试图用两个按钮创建一个UISegmentedControl,然后以编程方式删除一个,并且“有效”,因为它不会导致应用程序崩溃。我在 iOS 3 中有一个按钮,而在 iOS 4 中没有。有什么想法吗?

【问题讨论】:

这也困扰着我。我用它来代替“玻璃”按钮,Apple 还没有将它放入 SDK 的公共部分。 我曾经对 iOS3 中的彩色按钮做同样的事情,但他们似乎在 iOS4 中删除了此功能。 您似乎忘记了 nil 作为titles 数组中的第二个元素。请参阅下面的答案以获取工作代码。 arrayWithObject: 只接受一个参数。你在想arrayWithObjects: 对不起,你是对的。但底线是带有 nil 作为第二个参数的 arrayWithObjects 可以解决问题。 【参考方案1】:

你试过了吗:

[myButton removeAllSegments];
[myButton insertSegmentWithTitle:@"Press this" atIndex:0 animated:NO];

【讨论】:

是的,我试过了,它适用于设备,但不适用于模拟器。在模拟器中,我有一个空白按钮(根本不可见),但它在设备上显示良好,实际上是在运输应用程序中。【参考方案2】:

真的很奇怪。它在 iOS4 模拟器和设备中对我来说仍然可以正常工作(这是我的代码中真正有效的 sn-p):

NSArray *laterContent = [NSArray arrayWithObjects: @"Maybe later", nil];
UISegmentedControl *later = [[UISegmentedControl alloc] initWithItems:laterContent];
CGRect frame = CGRectMake(  20,
                          98,
                          self.alert.bounds.size.width/2 - 30,
                          30);

later.frame = frame;

later.selectedSegmentIndex = -1;

[later addTarget:self action:@selector(laterAction:) forControlEvents:UIControlEventValueChanged];

later.segmentedControlStyle = UISegmentedControlStyleBar;
later.tintColor = [UIColor colorWithRed:130.0f/255.0f green:74.0f/255.0f blue:54.0f/255.0f alpha:0.8f];
later.momentary = YES;
later.alpha = 0.9;

【讨论】:

当我按下单段按钮时,它会调用选择器,但不会显示正在按下的按钮。我错过了什么吗?【参考方案3】:

这不完全是与代码相关的解决方案,而是:我遇到了类似的问题,最终在 Photoshop 中绘制了我自己的外观相似的资源。做起来并不难,而且消除了一种特别糟糕的“代码味道”,IMO。

【讨论】:

【参考方案4】:

我发现如果您以前有一个带有单段 UISegmentedControl 的项目,您可以在 Interface Builder 中打开该项目和新项目,然后将单段 UISegmentedControl 拖动(或复制/粘贴)到新的视图控制器。它在您的应用程序和 Interface Builder 中都可以正常工作,只是不要将段数从 1 更改为其他任何值,因为它不会让您返回。我正在使用 Xcode 4.6.2 和 iOS 6。

【讨论】:

【参考方案5】:

Interface Builder 中的编辑器不允许您将分段数更改为小于 1,但您可以通过手动编辑 .xib xml 在 IB 中制作分段控件。

    右键单击包含分段控件的 .xib 从弹出菜单中选择Open As -> Source Code

    找到“<segments>”,它是 xml 段数组的开头。整个事情应该是这样的:

    <segments>
        <segment title="Segment 1 Title"/>
        <segment title="Segment 2 Title"/>
    </segments>
    

    只需删除&lt;segment title="Segment 2 Title"/&gt;,这样就只有一个段元素。

    再次右键单击 .xib 并选择 Open As -&gt; Interface Builder - iOS 以返回界面生成器。

您还应该将分段控件设置为“瞬时”模式。

我在编译或运行它时没有收到任何错误。当然,这是一种 hack,在某些情况下或在未来的 iOS 版本中可能会破坏某些东西。

【讨论】:

【参考方案6】:

两种可能:

1) 创建一个按钮并将背景图片设置为UISegmentedControl的单点

如果您的 SegmentedControl 是一个类变量,只需替换 @property

@property (nonatomic, retain) IBOutlet UIButton *button;

在 viewDidLoad-function 中添加以下内容

-(void) viewDidLoad

    [super viewDidLoad];
    ...
    self.button = [UIButton alloc] init];
    [self.button setBackgroundImage:[UIImage imageNamed:@"segmentedDot.png"] forState:(UIControlState)UIControlStateNormal];

2) 将段的数量设置为 UISegmentedControl 的三个,然后将宽度设置为 20 - 现在只显示中间的点。 不要忘记,如果用户与 UISegmentedControl 交互,请将 currentElement 再次设置为第二段,否则点将处于浅灰色而不是白色状态。

3) 在 InterfaceBuilder 中 UISegmentedControl 不需要的第二个点上放置一个按钮或一个小视图。确保背景颜色均匀。 当您使用按钮时,将属性检查器中“用户交互”的状态设置为禁用。作为类型,我会选择“自定义”,因为您的按钮中不会有一些边框;) 现在再次确定男性,第一个点始终是活动元素。

但是,我认为解决方案一应该是您应该采用的方式,因为 Apple 在禁用 1-dot-SegmentedControl 时对此进行了考虑。由于您将控件用作按钮,因此您正在寻找的元素 fpr 应该是一个按钮。 ;)

【讨论】:

【参考方案7】:

iOS 4 中没有解决方法。如果您需要此功能,请在bugreport.apple.com 提交错误(增强请求)。

【讨论】:

要求恢复旧功能作为增强功能是很奇怪的。目前还不清楚为什么这是一个问题......【参考方案8】:

您也可以使用removeSegmentAtIndex:animated:。如果您在情节提要或 xib 中创建具有两个段的分段控件,则可以像这样删除一个:

[self.sortButton removeSegmentAtIndex:1 animated:NO];

【讨论】:

以上是关于使用 UISegmentedControl 作为按钮的主要内容,如果未能解决你的问题,请参考以下文章

在 UINavigationController 中添加 UISegmentedControl 作为 titleView

UISegmentedControl 在 UITableView Header 上的行为很奇怪

iOS 7 中 UINavigationbar 下方的 UISegmentedControl

以编程方式在 UINavigationBar 下方的 UIToolbar 中添加 UISegmentedControl

UISegmentedControl 的使用

使用 UISegmentedControl 发送的无法识别的选择器