This question already has an answer here:
I've had two segmented controls stacked on top of each other, each with two options, so there's a 2x2 grid of filtering options for a search field. This has worked fine, but I just updated to Xcode 11 and UISegmentedControl.noSegment
has stopped working when I try to update it in response to user selection. However, it works when I set the initial value to .noSegment
in the property observer. isMomentary
is set to false. The outlets are all set up correctly. Is there some update to UISegmentedControl
behavior I'm missing, or is this a bug?
New, incorrect behavior shown here.
Current code that was working before, and stopped working after update:
@IBOutlet private weak var segmentedControlOne: UISegmentedControl!
@IBOutlet private weak var segmentedControlTwo: UISegmentedControl! {
didSet {
// Start with no segment selected on this control. This works!
segmentedControlTwo.selectedSegmentIndex = -1
}
}
@IBAction private func oneIndexChanged(_ sender: UISegmentedControl) {
//Turn off selection on second control while first is selected
segmentedControlTwo.selectedSegmentIndex = UISegmentedControl.noSegment
let i = sender.selectedSegmentIndex
if i == 0 {
searchType = .users
} else {
searchType = .contributors
}
}
@IBAction private func twoIndexChanged(_ sender: UISegmentedControl) {
//Turn off selection on first control while second is selected
segmentedControlOne.selectedSegmentIndex = UISegmentedControl.noSegment
let i = sender.selectedSegmentIndex
if i == 0 {
searchType = .articles
} else {
searchType = .categories
}
}
Thanks for asking this question. I ran into the same issue, so was great to get some confirmation it wasn't just something I was missing.
While Apple hopefully fixes this bug soon, I implemented the following workaround by recreating the segments. This code sample is based on a UISegmentedControl
with images as segments, you could of course implement the same approach for title strings:
public func resetSegmentedControl(_ control: UISegmentedControl) {
if #available(iOS 13, *) {
// workaround: recreate the segments
let numSegments = control.numberOfSegments
let segmentImages = (0..<numSegments).compactMap { control.imageForSegment(at: $0) }
control.removeAllSegments()
for (index, image) in segmentImages.enumerated() {
control.insertSegment(with: image, at: index, animated: false)
}
} else {
// for earlier versions of iOS, just reset the selectedSegmentIndex
control.selectedSegmentIndex = UISegmentedControl.noSegment
}
}
There's a slight flicker when removing and re-inserting the segments, but for me that's preferable to the broken state.
EDIT
As pointed out by @matt in the comment below, all that's needed is a call to setNeedsLayout
,i.e.:
control.selectSegmentIndex = .noSegment
control.setNeedsLayout()
来源:https://stackoverflow.com/questions/58067441/uisegmentedcontrol-nosegment-stopped-working-with-xcode-11-ios-13