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

梦想与她 提交于 2019-11-28 08:32:30

问题


I am the maintainer of STAControls which subclasses various UIControls, one of which is UISegmentedControl. Within that project's sample app, I have the following code (can be downloaded from the aforementioned 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;
    }
}

In iOS 13 the UISegmentedControlNoSegment assignment is not respected:

While in iOS 12 and prior versions of iOS this performs just fine:

Any idea(s) on how to work around this?


回答1:


The solutions given in the other answers are overblown. There is a much simpler workaround: just call setNeedsLayout on the segmented control.

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



回答2:


Remove the segment, then create it again. Here's a version in Swift, which only works if you've got text segments (not images). It assumes you've got an Storyboard with a segmented control and a button.

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
    }
}

In the Simulator, I couldn't see any flickering. After removing such a selected segment, selectedSegmentIndex becomes -2. This is a bit weird so that's why I added the last line of code, which sets it to the noSegment constant.




回答3:


Resolved and added a work around in STASegmentedControl. I did the following:

- (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];
}

Consult this link for the entire commit.



来源:https://stackoverflow.com/questions/57904625/specifying-uisegmentedcontrolnosegment-to-uisegmentedcontrols-selectedsegmentin

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!