Fixed on Xcode 11, Beta 5
When SegmentControl is inside a VStack and one of the segments is tapped, it may show more elements than it should. For a better understanding, see the screen capture:
Bug Report: FB6806169
Workaround: Yes, see below.
Last Version With Bug: Xcode 11, Beta 4.
Stackoverflow Question: https://stackoverflow.com/questions/57024678/using-swiftui-segmentedcontrol-with-sf-symbols-produces-odd-behavior/57027598#57027598
Sample Code
import SwiftUI
struct ContentView : View {
@State private var selectedSegment = 0
var body: some View {
VStack {
SegmentedControl(selection: $selectedSegment) {
Image(systemName: "hammer.fill").tag(0)
Image(systemName: "house.fill").tag(1)
Image(systemName: "desktopcomputer").tag(2)
}
Text("Selected Segment: \(selectedSegment)")
}
}
}
Workaround
By encapsulating the tab view, the problem goes away:
struct ContentView : View {
@State private var selectedSegment = 0
var body: some View {
VStack {
SegmentedControl(selection: $selectedSegment) {
TabItem(image: "hammer.fill", tag: 0)
TabItem(image: "house.fill", tag: 1)
TabItem(image: "desktopcomputer", tag: 2)
}
Text("Selected Segment: \(selectedSegment)")
}
}
}
struct TabItem: View {
let image: String
let tag: Int
var body: some View {
Image(systemName: image).tag(tag)
}
}
A variation of this bug seems to still exist. To trigger it, simply toggle light/dark mode. With the code below, toggling Darkmode will add an extra “Scribble” to the segmented control. Note the Picker doesn’t need to be in a VStack, and unfortunately your workaround doesn’t work on this bug.
struct ContentView: View {
//MARK: picker
@State var settingsMode = 0
var settings = [“paintbrush”, “scribble”]
var body: some View {
Picker(“Stroke/Color Settings”, selection: $settingsMode) {
ForEach(0 ..< settings.count) { index in
//TabItem(image: self.settings[index], tag: index)
Image(systemName: self.settings[index])
.tag(index)
}
}
.pickerStyle(SegmentedPickerStyle())
.frame(width: 70)
}
}