SwiftUI modal with textField

Hello, thank you for the SiftUI tutorials. They have been so much helpful to me.

I want to create a modal, a pop up or an alert (I’m not sure how to call it) with a textField in it using SwiftUI. Please help me out.

You might have to define a custom Alert to achieve what you want since native Alerts in SwiftUI cannot cater for adding a TextField (at least not that I know of).

This stackoverflow thread might help:

Thank, but I’ve tried the solutions here and didn’t seem to work.

Here is my take on a Custom Alert with TextField.

import SwiftUI

struct CustomAlert: View {
    @Binding var textEntered: String
    @Binding var showingAlert: Bool
    
    var body: some View {
        ZStack {
            RoundedRectangle(cornerRadius: 20)
                .fill(Color.white)
            VStack {
                Text("Custom Alert")
                    .font(.title)
                    .foregroundColor(.black)
                
                Divider()
                
                TextField("Enter text", text: $textEntered)
                    .padding(5)
                    .background(Color.gray.opacity(0.2))
                    .foregroundColor(.black)
                    .padding(.horizontal, 20)
                
                Divider()
                
                HStack {
                    Button("Dismiss") {
                        self.showingAlert.toggle()
                    }
                }
                .padding(30)
                .padding(.horizontal, 40)
            }
        }
        .frame(width: 300, height: 200)
    }
}

struct ContentView: View {
    @State private var textEntered = ""
    @State private var showingAlert = false
    
    var body: some View {
        NavigationView {
            ZStack {
                Color.red.opacity(0.3)
                    .edgesIgnoringSafeArea(.all)
                
                VStack(spacing: 20) {
                    Button("Show Alert") {
                        self.showingAlert.toggle()
                        self.textEntered = ""
                    }
                    Text("\(textEntered)")
                }
                
                CustomAlert(textEntered: $textEntered, showingAlert: $showingAlert)
                    .opacity(showingAlert ? 1 : 0)
                
            }
        .navigationBarTitle("Custom Alert")
            .navigationBarItems(leading:
                Button(action: {
                    self.showingAlert.toggle()
                }) {
                    Image(systemName: "play.fill")
            })
        }
        
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

Thank you, this one did so much good.

It needs a bit of work to make it a really useful Alert that can be called from anywhere. I just put this together as an exercise. For one thing, part of the Alert is obscured by the keyboard on my Simulator so that needs to be fixed so that the Alert window moves up as the keyboard appears.

This is great @Chris_Parker. I am using this in the Stock Challenge for this month. Thanks!

I modified it so that it will just replace the current view with the Alert View.

ContentView.swift

import SwiftUI

struct ContentView: View {
    @State private var textEntered = "Default"
    @State private var showingAlert = false
    
    
    var body: some View {
        if showingAlert == true {
            CustomAlert(textEntered: $textEntered, showingAlert: $showingAlert)//.opacity(showingAlert ? 1 : 0)
            
        } else {
            VStack {
                Button("Show Alert") {
                    print("About tapped!")
                
                    self.showingAlert.toggle()
                   
                }
                Text("textEntered = \(textEntered)")
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

CustomAlert.swift

import SwiftUI

struct CustomAlert: View {
    @Binding var textEntered: String
    @Binding var showingAlert: Bool
    
    var body: some View {
        ZStack {
            RoundedRectangle(cornerRadius: 20)
                .fill(Color.white)
            VStack {
                Text("Custom Alert")
                    .font(.title)
                    .foregroundColor(.black)
                
                Divider()
                
                TextField("Enter text", text: $textEntered)
                    .textCase(.uppercase)
                    .padding(5)
                    .background(Color.gray.opacity(0.2))
                    .foregroundColor(.black)
                    .padding(.horizontal, 20)
                    
                    
                Divider()
                
                HStack {
                    Button("Dismiss") {
                        self.showingAlert.toggle()
                    }
                }
                .padding(30)
                .padding(.horizontal, 40)
            }
        }
        .frame(width: 300, height: 200)
    }
}




1 Like