使用UISegmentedControl作为按钮

7

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

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

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

"分段控件的分段数属性必须大于或等于2。"

我有点困惑。有没有解决方法?我尝试创建一个具有两个按钮的UISegmentedControl,然后通过编程方式删除一个按钮,这样做“有效”,因为它不会导致应用程序崩溃。但是在iOS 3中,我得到了一个按钮,在iOS 4中则什么都没有。有任何想法吗?


这也困扰着我。我正在使用它来替换“玻璃”按钮,因为苹果仍未将其放入SDK的公共部分中。 - Shaggy Frog
我曾经在iOS3中为彩色按钮做同样的事情,但是它们似乎在iOS4中删除了这个功能。 - Vibhor Goyal
看起来你忘记在标题数组中加入 nil 作为第二个元素了。请查看下面的答案获取可用的代码。 - spbfox
arrayWithObject: 只接受一个参数。你可能想使用 arrayWithObjects:。 - Adolfo
抱歉,你是对的。但归根结底,使用 nil 作为第二个参数的 arrayWithObjects 方法就可以解决问题。 - spbfox
8个回答

7

你尝试过这个吗:

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

是的,我尝试过这个方法,它可以在设备上运行,但模拟器上不行。在模拟器上,我得到了一个空白按钮(即根本看不见),但在设备上显示正常,并且实际上已经在一个发布的应用程序中使用。 - Adolfo

6

真的很奇怪。在iOS4模拟器和设备上,我仍然可以正常使用它(这是我代码中实际可工作的片段):

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;

1
当我按下单个段按钮时,它确实调用了选择器,但它没有显示按钮被按下。我有什么遗漏吗? - Wayne Lo

3

虽然不是与代码直接相关的解决方案,但我曾遇到类似的问题,并在 Photoshop 中绘制了自己相似外观的资源。这并不是特别困难的事情,而且在我的看法中去除了一种糟糕的“代码气味”。


1
在Interface Builder中,编辑器不允许您将分段控件的分段数更改为少于1,但是您可以通过手动编辑.xib的xml来创建一个分段控件。
  1. 右键点击包含分段控件的.xib文件
  2. 从弹出菜单中选择打开方式 -> 源代码
  3. 找到"<segments>",这是xml数组段的开始。整个东西应该看起来像:

    <segments>
        <segment title="Segment 1 Title"/>
        <segment title="Segment 2 Title"/>
    </segments>
    
  4. 只需删除<segment title="Segment 2 Title"/>,使只有一个段元素。

  5. 再次右键单击.xib文件并选择打开方式 -> 接口生成器 - iOS返回接口生成器。
你也应该将分段控件设置为“短暂”的模式。
我在编译和运行中没有遇到任何错误。当然,这只是一种hack方法,在某些情况下或未来的iOS版本中可能会出现问题。

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

0

有两种可能:

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

如果您的SegmentedControl是类变量,请替换@property

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

在viewDidLoad函数中添加以下内容
-(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的不需要的第二个点上放置一个按钮或小视图。确保背景颜色均匀。 如果您使用按钮,请在属性检查器中将“用户交互”状态设置为禁用。作为类型,我会选择“自定义”,因为您的按钮中不会有一些边框;) 现在再次确保始终第一个点是活动元素。

然而,我认为解决方案一应该是您应该采取的方式,因为当他们禁用1点式分段控件时,苹果考虑了一些东西。由于您正在将控件用作按钮,因此您正在寻找的元素应该是按钮。;)


0

您还可以使用removeSegmentAtIndex:animated:。如果您在Storyboard或Xib中创建了一个只有两个分段的分段控件,可以像这样删除其中一个:

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

0

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


将旧功能恢复的请求视为增强功能,这种想法很奇怪。目前仍不清楚这是什么问题的原因... - Shaggy Frog

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接