I've got a list of message examples that use string interpolation to make the example more relevant to the user. Because I've found that you cannot use variables before you initiate the class, it is created as an empty [String] , and then assigned a value after the init() . However, the variables used in the strings are then changed using a picker. Additionally, the class is used as an @EnvironmentVariable , and so everything is sent to a publisher when changed, which is where I think the problem lies – I think there is some problem with the interpolation that doesn't let it subscribe to the publisher changes.

The class is defined as such:

class GlobalVars: ObservableObject { let objectWillChange = PassthroughSubject<GlobalVars,Never>() var listToChooseFrom: [String] = [ "a list", "of options", "to be chosen from" ] { didSet { objectWillChange.send(self) } } var listPos: Int = 0 { didSet { objectWillChange.send(self) } } var stringToChange: String { didSet { objectWillChange.send(self) } } var output: [String] { didSet { objectWillChange.send(self) } } init() { switch listPos { case 0: stringToChange = "a value" case 1: stringToChange = "another value" default: stringToChange = "toodleydoo" } output = [ "a list", "with several variables", "defined above", "and one modified within the init() statement", "referenced within strings", "like \(stringToChange)." ] } }

The picker is defined as such, and changes the value of listPos relative to listToChooseFrom :

Picker("Select an option", selection: $globalVars.listPos) { ForEach(0 ..< globalVars.listToChooseFrom) { Text("\(self.globalVars.listToChooseFrom[$0])") } }