Is there any alternative for onChange(of: selection) in Swift 3?

Is there any alternative in Swift 3 if a @State variable change?

Answered by Claude31 in 750883022

What do you mean ? Alternative to what, to do what ?

Please explain context:

  • show code
  • what do you want to change
  • for what reason

Consider this simple code:

struct ContentView: View {
    @State var isPlaying = true
    @State var moreText = "Is playing"

    var body: some View {
        Button("Change") {
            isPlaying.toggle()
        }

        Text("\(moreText)")
            .onChange(of: isPlaying, perform: { _ in
                if isPlaying {
                    moreText = "Is playing"
                } else {
                    moreText = "Not playing"
                }
            })
    }
}

You can replace onChange by:

struct ContentView: View {
    @State var isPlaying = true
    @State var moreText = "Is playing"

    var body: some View {
        Button("Change") {
            isPlaying.toggle()
        }
        if isPlaying {
            Text("Is playing")
        } else {
            Text("Not playing")
        }

    }
}

But now, if you want to update another value (a counter for instance) when isPlaying changes, you can use onChange to perform the counter increment in the perform closure:

struct ContentView: View {
    @State var isPlaying = true
    @State var num = 0
    @State var moreText = "Is playing 0 time"

    var body: some View {
        Button("Change") {
            isPlaying.toggle()
        }

        Text("\(moreText)")
            .onChange(of: isPlaying, perform: { _ in
                if isPlaying {
                    num += 1     // change value in closure
                    moreText = "Is playing \(num) times"
                } else {
                    moreText = "Not playing"
                }
            })
        
    }
}

But you cannot do it in the if isPlaying: that causes a compilation error:

struct ContentView: View {
    @State var isPlaying = true
    @State var num = 0

    var body: some View {
        Button("Change") {
            isPlaying.toggle()
        }
        if isPlaying {
            num += 1      // ERROR HERE: Type '()' cannot conform to 'View', because I need to have a vView here
            Text("Is playing \(num) times")
        } else {
            Text("Not playing")
        }

    }
}
Accepted Answer

What do you mean ? Alternative to what, to do what ?

Please explain context:

  • show code
  • what do you want to change
  • for what reason

Consider this simple code:

struct ContentView: View {
    @State var isPlaying = true
    @State var moreText = "Is playing"

    var body: some View {
        Button("Change") {
            isPlaying.toggle()
        }

        Text("\(moreText)")
            .onChange(of: isPlaying, perform: { _ in
                if isPlaying {
                    moreText = "Is playing"
                } else {
                    moreText = "Not playing"
                }
            })
    }
}

You can replace onChange by:

struct ContentView: View {
    @State var isPlaying = true
    @State var moreText = "Is playing"

    var body: some View {
        Button("Change") {
            isPlaying.toggle()
        }
        if isPlaying {
            Text("Is playing")
        } else {
            Text("Not playing")
        }

    }
}

But now, if you want to update another value (a counter for instance) when isPlaying changes, you can use onChange to perform the counter increment in the perform closure:

struct ContentView: View {
    @State var isPlaying = true
    @State var num = 0
    @State var moreText = "Is playing 0 time"

    var body: some View {
        Button("Change") {
            isPlaying.toggle()
        }

        Text("\(moreText)")
            .onChange(of: isPlaying, perform: { _ in
                if isPlaying {
                    num += 1     // change value in closure
                    moreText = "Is playing \(num) times"
                } else {
                    moreText = "Not playing"
                }
            })
        
    }
}

But you cannot do it in the if isPlaying: that causes a compilation error:

struct ContentView: View {
    @State var isPlaying = true
    @State var num = 0

    var body: some View {
        Button("Change") {
            isPlaying.toggle()
        }
        if isPlaying {
            num += 1      // ERROR HERE: Type '()' cannot conform to 'View', because I need to have a vView here
            Text("Is playing \(num) times")
        } else {
            Text("Not playing")
        }

    }
}
Is there any alternative for onChange(of: selection) in Swift 3?
 
 
Q