为 UISegmentedControl 的 selectedSegmentIndex 指定 UISegmentedControlNoSegment 对 iOS 13 没有影响

Specifying UISegmentedControlNoSegment to UISegmentedControl's selectedSegmentIndex has no Effect on iOS 13

我是 STAControls 的维护者,它对各种 UIControl 进行了子类化,其中之一是 UISegmentedControl。在该项目的示例应用程序中,我有以下代码(可以从上述 link 下载):

- (void)textFieldDidEndEditing:(UITextField *)textField {
    NSInteger integer = [textField.text integerValue];
    if (integer < 0 || integer >= self.segmentedControl.numberOfSegments) { this doesn't work
        self.segmentedControl.selectedSegmentIndex = UISegmentedControlNoSegment;
    } else { // this works
        self.segmentedControl.selectedSegmentIndex = integer;
    }
}

在 iOS 13 中,UISegmentedControlNoSegment 赋值不被遵守:

虽然在 iOS 12 和 iOS 之前的版本中,这表现得很好:

关于如何解决这个问题的任何想法?

删除细分,然后重新创建。这是 Swift 中的一个版本,它仅在您有文本段(不是图像)时才有效。它假设您有一个带有分段控件和按钮的故事板。

class ViewController: UIViewController {
    @IBOutlet weak var segmentedControl: UISegmentedControl!

    @IBAction func clearSegmentedControl(_ sender: Any) {
        guard segmentedControl.selectedSegmentIndex >= 0 else {
            return
        }

        let index = self.segmentedControl.selectedSegmentIndex
        let title = self.segmentedControl.titleForSegment(at: index) ?? ""

        self.segmentedControl.removeSegment(at: self.segmentedControl.selectedSegmentIndex, animated: false)
        self.segmentedControl.insertSegment(withTitle: title, at: index, animated: false)
        self.segmentedControl.selectedSegmentIndex = UISegmentedControl.noSegment
    }
}

在模拟器中,我看不到任何闪烁。删除这样一个选定的段后,selectedSegmentIndex 变为 -2。这有点奇怪,所以我添加了最后一行代码,将其设置为 noSegment 常量。

已解决并在 STASegmentedControl 中添加了变通方法。我做了以下事情:

- (void)setSelectedSegmentIndex:(NSInteger)selectedSegmentIndex {
    if (@available(iOS 13.0, *)) {
        if (selectedSegmentIndex == UISegmentedControlNoSegment && self.selectedSegmentIndex >= 0
            && !self.handlingNoSegment)
        {
            self.handlingNoSegment = YES;
            NSUInteger index = self.selectedSegmentIndex;
            NSString *title = [self titleForSegmentAtIndex:self.selectedSegmentIndex];
            [self removeSegmentAtIndex:self.selectedSegmentIndex animated:NO];
            [self insertSegmentWithTitle:title atIndex:index animated:NO];
        }
        self.handlingNoSegment = NO;
    }
    [super setSelectedSegmentIndex:selectedSegmentIndex];
}

请参阅 this link 了解整个提交。

其他答案中给出的解决方案被夸大了。有一个更简单的解决方法:只需在分段控件上调用 setNeedsLayout

self.seg.selectedSegmentIndex = UISegmentedControl.noSegment
self.seg.setNeedsLayout()