UISegmentedControl 不会取消选择旧段
Posted
技术标签:
【中文标题】UISegmentedControl 不会取消选择旧段【英文标题】:UISegmentedControl Doesn't Deselect Old Segment 【发布时间】:2014-10-25 22:12:40 【问题描述】:我在 UITableView 表行中有一个 UISegmentedControl。选择触发,新的段被突出显示。问题是,旧段仍处于选中状态。
如果我关闭并重新打开包含表格的弹出框,则会显示正确的段索引。
我正在运行 XCode 6.1 并在 ios 7.1 模拟器上进行测试。
感谢您的帮助。
UITableViewCell *segmentCell = [tableView dequeueReusableCellWithIdentifier:segmentCellIdentifier];
if (segmentCell == nil)
segmentCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:segmentCellIdentifier];
segmentCell.backgroundColor = [UIColor clearColor];
segmentCell.backgroundView = nil;
NSArray *segmentItems = [NSArray arrayWithObjects: NSLocalizedString(@"settingsBackgroundCork", @"Cork - Select cork background theme"), NSLocalizedString(@"settingsBackgroundDark", @"Dark - Select dark background theme"), NSLocalizedString(@"settingsBackgroundLight", @"Light - Select light background theme"), nil];
self.backgroundSegmentedControl = [[UISegmentedControl alloc] initWithItems: segmentItems];
[self.backgroundSegmentedControl addTarget:self action:@selector(backgroundControlChanged:) forControlEvents: UIControlEventValueChanged];
self.backgroundSegmentedControl.frame = CGRectMake(10, 6, 300, 32);
NSInteger background = [[NSUserDefaults standardUserDefaults] integerForKey:kUserDefaultsBackgroundSelection];
self.backgroundSegmentedControl.selectedSegmentIndex = background;
self.backgroundSegmentedControl.momentary = NO;
[segmentCell.contentView addSubview:self.backgroundSegmentedControl];
cellToReturn = segmentCell;
这是在段选择时调用的方法:
- (void)backgroundControlChanged:(UISegmentedControl *)control
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setInteger:control.selectedSegmentIndex forKey:kUserDefaultsBackgroundSelection];
self.backgroundSegmentedControl.selectedSegmentIndex = control.selectedSegmentIndex;
[self.backgroundSegmentedControl setNeedsDisplay];
[[NSNotificationCenter defaultCenter] postNotificationName:kPageBackgroundShouldChangeNotification object:nil];
【问题讨论】:
您的表格视图是否滚动,如果是,您是否只有在滚动后才能看到这种效果? tableview 可以滚动。也就是说,该元素位于顶部,并且无需滚动即可显示。测试时我没有滚动(即没有重绘行)。 我可以复制您的问题的唯一方法是滚动。您的代码存在的一个问题是,当您重用一个单元格时,您将在旧控制器之上添加新的分段控制器。最好创建一个子类单元格,并在其 init 方法中添加分段控件。或者,您可以在将单元格添加到 cellFroRowAtIndexPath 之前检查单元格是否包含分段控件。 我遇到了同样奇怪的问题。如果我将分段控件的创建放在 dispatch_async(dispatch_get_main_queue(), ^) 块中,结果会有所不同,但它仍然不能正确运行。我完全从头开始制作类似的控件。这确实是一个奇怪的问题。 【参考方案1】:奇怪的错误 - 我以前从未见过这个。两个建议:
尝试在处理程序中再次设置selectedSegmentIndex
,然后
尝试在那里的控件上调用setNeedsDisplay
。
momentary
默认为NO
,所以不需要设置。
另外,在selectedSegmentIndex
文档中它说:
默认值是 UISegmentedControlNoSegment (没有选择段),直到用户触摸一个段。将此属性设置为 -1 以关闭当前选择。
也许你也想试试这最后一件事。
【讨论】:
感谢您的建议。我已经尝试了您的前 2 个建议,但无济于事。更新了上面的代码示例。我也试过你的 -1 来关闭选择,但是分段控件根本没有注册选择。【参考方案2】:我能够通过将我对 setSelectedSegmentIndex 的调用移至 setNeedsLayout 函数内部来解决此问题,而不是在创建 UISegmentedControl 后立即调用它。当然,我还必须创建一个变量来跟踪应该选择哪个段。
【讨论】:
【参考方案3】:有同样的问题。通过在添加新实例之前从 superview 中删除 segmentedControl 的前一个实例来解决它。
在将 segmentedControl 的新实例添加到父视图之前,添加下面提到的 3 行代码以删除先前的 segmentedControl。
self.backgroundSegmentedControl.tag = 101
if let foundView2 = segmentCell.contentView.viewWithTag(101)
foundView2.removeFromSuperview()
[segmentCell.contentView addSubview:self.backgroundSegmentedControl];
【讨论】:
以上是关于UISegmentedControl 不会取消选择旧段的主要内容,如果未能解决你的问题,请参考以下文章
如何检查用户是不是选择了 UISegmentedControl?
使用 UISegmentedControl 发送的无法识别的选择器
选择 UISegmentedControl 控件会导致 SIGABRT
从 UITableView didSelectRowAtIndexPath 检测 UISegmentedControl 中的选择更改