Your First iOS & SwiftUI App: Polishing the App, Episode 7: Challenge: Extract Views | Kodeco

Practice extracting views by extracting reusable slider text, slider, and hit me button views.


This is a companion discussion topic for the original entry at https://www.kodeco.com/38052670-your-first-ios-swiftui-app-polishing-the-app/lessons/7

Hello, this challenge is constructive for me to understand; extract, MV, and binding. Is it ok that i created a separate button view file and used it in the content view? My aim here is if i need a button for some reason, I can use it.

struct HitMeButton: View {
  @Binding var alertIsVisible: Bool
  @Binding var game: Game
  @Binding var sliderValue: Double
  
  // here i have a problem
  
  var body: some View {
    let roundedValue = Int(sliderValue.rounded())
    ButtonView(buttonText: "Hit Me",
               AlertText: "Hello There",
               alertMessage: "The slider's value is \(roundedValue). You scored \(game.points(sliderValue: roundedValue )) points this round.",
               alertIsVisible: alertIsVisible)
  }
}```


// separate buttonview file 

import SwiftUI

struct ButtonView: View {
  
  var buttonText: String
  var AlertText: String
  var alertMessage: String
  @State var alertIsVisible: Bool
  
  var body: some View {
    VStack{
      Button(buttonText.uppercased()) {
        alertIsVisible = true
      }
      .padding(20.0)
      .background(
        ZStack {
          Color("ButtonColor")
          LinearGradient(
            gradient: Gradient(colors: [Color.white.opacity(0.3), Color.clear]),
            startPoint: .top, endPoint: .bottom)
        }
      )
      .foregroundColor(.white)
      .cornerRadius(21.0)
      .bold()
      .font(.title3)
      .alert(
        AlertText,
        isPresented: $alertIsVisible,
        actions: {
          Button("Awesome") {
            print("Alert closed")
          }
        },
        message: {
          Text(alertMessage)
        }
      )
    }
  }
  
}

struct ButtonView_Previews: PreviewProvider {
  static var previews: some View {
    ButtonView(buttonText: "Button Text", AlertText: "AlertText", alertMessage: "alertMessage", alertIsVisible: false)
  }
}

Hi there! I think the issue you’re seeing is because you are keeping the state of alertIsVisible in ButtonView, which is fine, but you’re trying to also have a binding to it in HitMeButton. If you’re using ButtonView to track the state of the alert, and you’re using it to present the alert, you don’t need that information in HitMeButton at all.

1 Like