1

I have to generate a random string on a button click (in the first view) and then display the string on a text (in the second view) but right now I'm stuck at toggling the second view with the text. Does someone know how I can bind the return value from the func and display it to the second view?

this is the code for random string (credit: Generate random alphanumeric string in Swift)

class randomString: ObservableObject{ 
  @Published var showDisplay: Bool = false
  @Published var s = ""

  func randomString(of length: Int) -> String { // return `String`
      let letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
      var s = ""
      for _ in 0 ..< length {
          s.append(letters.randomElement()!)
          print(s)
        
          goToDisplay()
      }
      return s
  }

  func goToDisplay(){
    
      self.showDisplay.toggle()
  }
}

In the Content View I call the function from button click;

struct ContentView: View {

   @StateObject var stringData = randomString()

   var body: some View {
    
       VStack{
           Text("Generate String")
               .font(.title)
               .fontWeight(.bold)
               .foregroundColor(.primary)
               .padding()
        
           Button(action: {
               //self.showDisplay.toggle()
               stringData.randomString(of: 5)
           }, label: {
               Text("Next Page")
                   .font(.title2)
                   .fontWeight(.light)
                   .foregroundColor(Color.white)
                   .scaledToFit()
                   .frame(maxWidth: .infinity)
                   .frame(height: 60, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/)
                   .background(Color.orange)
                   .cornerRadius(20)
                   .padding(.all,10)


           })
           .padding(.bottom, 40)
       }
       .fullScreenCover(isPresented: $stringData.goToDisplay, content: {
           DisplayView()
       })

    }
}

And Second View looks like this for now

struct DisplayView: View {

   @StateObject var stringData = randomString()
   @Environment(\.presentationMode) var presentationMode

   var body: some View {
       Text("Random String : \(stringData.s)")
           .font(.title)
           .fontWeight(.bold)
           .foregroundColor(.primary)
           .padding()
    
       Spacer()
    
       Button(action: {
           presentationMode.wrappedValue.dismiss()
       }, label: {
          Text("Close")
               .font(.title2)
               .fontWeight(.light)
               .foregroundColor(Color.white)
               .scaledToFit()
               .frame(width: UIScreen.main.bounds.width - 100)
               .frame(height: 50)
               .scaledToFit()
               .background(Color.orange)
               .cornerRadius(12)
               .padding(.bottom)
       })
       .padding(.horizontal)
   }
}

1 Answer 1

1

Just change your flow.

class RandomString: ObservableObject{
    
    @Published var s: String? = ""
    
    func randomString(of length: Int) { // return `String`
        let letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
        var s = ""
        for _ in 0 ..< length {
            s.append(letters.randomElement()!)
            print(s)
        }
        self.s = s
    }
}

struct ContentViewSecond: View {
    
    @StateObject var stringData = RandomString()
    @State var showDisplay = false
    var body: some View {
        
        VStack{
            Text("Generate String")
                .font(.title)
                .fontWeight(.bold)
                .foregroundColor(.primary)
                .padding()
            
            Button(action: {
                self.showDisplay.toggle()
                stringData.randomString(of: 5)
            }, label: {
                Text("Next Page")
                    .font(.title2)
                    .fontWeight(.light)
                    .foregroundColor(Color.white)
                    .scaledToFit()
                    .frame(maxWidth: .infinity)
                    .frame(height: 60, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/)
                    .background(Color.orange)
                    .cornerRadius(20)
                    .padding(.all,10)
                
                
            })
            .padding(.bottom, 40)
        }
        .fullScreenCover(isPresented: $showDisplay) {
            DisplayView(stringData: stringData)
        }
    }
}

struct DisplayView: View {
    
    @ObservedObject var stringData: RandomString
    @Environment(\.presentationMode) var presentationMode

    var body: some View {
        Text("Random String : \(stringData.s ?? "")")
            .font(.title)
            .fontWeight(.bold)
            .foregroundColor(.primary)
            .padding()
     
        Spacer()
     
        Button(action: {
            presentationMode.wrappedValue.dismiss()
        }, label: {
           Text("Close")
                .font(.title2)
                .fontWeight(.light)
                .foregroundColor(Color.white)
                .scaledToFit()
                .frame(width: UIScreen.main.bounds.width - 100)
                .frame(height: 50)
                .scaledToFit()
                .background(Color.orange)
                .cornerRadius(12)
                .padding(.bottom)
        })
        .padding(.horizontal)
    }
 }
Sign up to request clarification or add additional context in comments.

2 Comments

@StateObject should act like a single source of truth, isn’t declaring “@StateObject var stringData: RandomString” incorrect in DisplayView?
@TusharSharma your point is right. but I just reuse OP code so. You can edit my ans.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.