Swift: Insert Alert Box with Text Input (And Store Text Input )

Swift: Insert Alert Box with Text Input (and Store Text Input )

Check this out:

let alertController = UIAlertController(title: "Email?", message: "Please input your email:", preferredStyle: .alert)

let confirmAction = UIAlertAction(title: "Confirm", style: .default) { (_) in
guard let textFields = alertController.textFields,
textFields.count > 0 else {
// Could not find textfield
return
}

let field = textFields[0]
// store your data
UserDefaults.standard.set(field.text, forKey: "userEmail")
UserDefaults.standard.synchronize()
}

let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) { (_) in }

alertController.addTextField { (textField) in
textField.placeholder = "Email"
}

alertController.addAction(confirmAction)
alertController.addAction(cancelAction)

self.present(alertController, animated: true, completion: nil)

Is it possible to save the text entered into an alert's textfield in SwiftUI and display it in the app like this - Text( alert text input here )?

You will want to grab the value of the text field from inside the Done button's handler. So all you need to do is move the bracket down:

alert.addAction(UIAlertAction(title: "Done", style: .default) { _ in
let textField = alert.textFields![0] as UITextField
alertInput = textField.text ?? "Name"
})

The code inside this closure is called when the user taps this UIAlertAction you have set up.

Note that if the field is left empty, the value of textField.text will be "" and not nil, so in order to use the default value you provide, you may need some additional logic here to check for a blank string as well.

UITEXTFIELD input data to alert box ok clicked

I think your code is fine, only need to do a little changes.You need to return Combined string from this method.

Update below method.

func getvalueoftextfield() -> String {
let UserDestination: String = Choose_Destination.text!
print(UserDestination)

let UserDenomination: String = Choose_Denomination.text!
print(UserDenomination)

let UserEnteredDenomination: String = manual_denominaton_textfield.text!
print(UserEnteredDenomination)

let UserEmail: String = Email_textfield.text!
print(UserEmail)

let UserEnteredEmailConfirm: String = confirm_email_validation.text!
print(UserEnteredEmailConfirm)

let UserEnteredReceiversName: String = receivers_name_textfirld.text!
print(UserEnteredReceiversName)

let UserEnteredSendersName: String = senders_name_textfield.text!
print(UserEnteredSendersName)

let UserMessage: String = message_textView.text!
print(UserMessage)

let datacombined = String(format: "%@\n%@\n%@\n%@\n%@\n%@\n%@\n%@", UserDestination, UserDenomination, UserEnteredDenomination, UserEmail, UserEnteredEmailConfirm, UserEnteredReceiversName, UserEnteredSendersName, UserMessage
)

return datacombined
}

Show UIAlertController like this.

alert.addAction(UIAlertAction(title: "Agree", style: UIAlertActionStyle.default, handler: self.getvalueoftextfield()))

OR

let alertController = UIAlertController(title: AppName, message: self.getvalueoftextfield(), preferredStyle: .alert)
let OKAction = UIAlertAction(title: "OK", style: .default) { (action:UIAlertAction!) in

}

alertController.addAction(OKAction)
self.navigationController?.present(alertController, animated: true, completion: nil)

How to display user input in an Alert? (SWIFT)

This is because mealNameLabel.text is an Optional. Optionals are declared with a ? and the text value of UILabels is of type String?. To access the underlying value, you have to unwrap it by using !, so your code would have to be

let alertController = UIAlertController(title: "Hello, \(mealNameLabel.text!))", message: "Enjoy our new app and make sure you rate us in AppStore!", preferredStyle: .alert)

However, if the value of the label is nil, your app would crash. See the post about it for more info if your app crashes while unwrapping it.

Get input value from TextField in iOS alert in Swift

Updated for Swift 3 and above:

//1. Create the alert controller.
let alert = UIAlertController(title: "Some Title", message: "Enter a text", preferredStyle: .alert)

//2. Add the text field. You can configure it however you need.
alert.addTextField { (textField) in
textField.text = "Some default text"
}

// 3. Grab the value from the text field, and print it when the user clicks OK.
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { [weak alert] (_) in
let textField = alert.textFields![0] // Force unwrapping because we know it exists.
print("Text field: \(textField.text)")
}))

// 4. Present the alert.
self.present(alert, animated: true, completion: nil)

Swift 2.x

Assuming you want an action alert on iOS:

//1. Create the alert controller.            
var alert = UIAlertController(title: "Some Title", message: "Enter a text", preferredStyle: .Alert)

//2. Add the text field. You can configure it however you need.
alert.addTextFieldWithConfigurationHandler({ (textField) -> Void in
textField.text = "Some default text."
})

//3. Grab the value from the text field, and print it when the user clicks OK.
alert.addAction(UIAlertAction(title: "OK", style: .Default, handler: { [weak alert] (action) -> Void in
let textField = alert.textFields![0] as UITextField
println("Text field: \(textField.text)")
}))

// 4. Present the alert.
self.presentViewController(alert, animated: true, completion: nil)

Display an Alert with Text Field Entry

UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Enter Text"
message:@"Enter some text below"
preferredStyle:UIAlertControllerStyleAlert];

UIAlertAction *submit = [UIAlertAction actionWithTitle:@"Submit" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {

if (alert.textFields.count > 0) {

UITextField *textField = [alert.textFields firstObject];

textField.text // your text
}

}];

[alert addAction:submit];

[alert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
textField.placeholder = @"something"; // if needs
}];

[self presentViewController:alert animated:YES completion:nil];

How to get the input text from the TextField in an alert

You need to use the same logic as in Swift: write alert.textFields[0].text inside the action handler in the following way:

UIAlertAction *ok = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
NSString *input = alert.textFields[0].text;
NSLog(@"input was '%@'", input);
}];

Which in my test prints

input was '1234'

Getting text value from alert box

your ok action handler(closure) will call when you click on ok button. so instead of assign value to local variable sessionName , make a sessionName variable in class.

class YourClass {
var sessionName: String?

...

@IBAction func btnSaveSession(sender: AnyObject) {

//Prompt user to enter session name

promptUserToEnterSessionName("Save Session", message: "Please enter the name of your custom session below.");

}

func promptUserToEnterSessionName(title: String, message: String) {

//1. Create the alert controller.
let alert = UIAlertController(title: title, message: message, preferredStyle: .Alert)

//2. Add the text field. You can configure it however you need.
alert.addTextFieldWithConfigurationHandler({ (textField) -> Void in
textField.text = "Enter session name."
})

//3. Grab the value from the text field, and print it when the user clicks OK.
alert.addAction(UIAlertAction(title: "OK", style: .Default, handler: { (action) -> Void in
let textField = alert.textFields![0] as UITextField
print("Text field: \(textField.text)")
self.sessionName = textField.text!
self.testDemo()
}))

// 4. Present the alert.
self.presentViewController(alert, animated: true, completion: nil)

}

fun TestDemo() {
print("session Name: " + self.sessionName)

//Save session to firebase.

//redirect to create session controller.

}
}

How to add a TextField to Alert in SwiftUI?

As the Alert view provided by SwiftUI doesn't do the job you will need indeed to use UIAlertController from UIKit. Ideally we want a TextFieldAlert view that we can presented in the same way we would present the Alert provided by SwiftUI:

struct MyView: View {

@Binding var alertIsPresented: Bool
@Binding var text: String? // this is updated as the user types in the text field

var body: some View {
Text("My Demo View")
.textFieldAlert(isPresented: $alertIsPresented) { () -> TextFieldAlert in
TextFieldAlert(title: "Alert Title", message: "Alert Message", text: self.$text)
}
}
}

We can achieve this writing a couple of classes and adding a modifier in a View extension.

1) TextFieldAlertViewController creates a UIAlertController (with a text field of course) and presents it when it appears on screen. User changes to the text field are reflected into a Binding<String> that is passed during initializazion.

class TextFieldAlertViewController: UIViewController {

/// Presents a UIAlertController (alert style) with a UITextField and a `Done` button
/// - Parameters:
/// - title: to be used as title of the UIAlertController
/// - message: to be used as optional message of the UIAlertController
/// - text: binding for the text typed into the UITextField
/// - isPresented: binding to be set to false when the alert is dismissed (`Done` button tapped)
init(title: String, message: String?, text: Binding<String?>, isPresented: Binding<Bool>?) {
self.alertTitle = title
self.message = message
self._text = text
self.isPresented = isPresented
super.init(nibName: nil, bundle: nil)
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

// MARK: - Dependencies
private let alertTitle: String
private let message: String?
@Binding private var text: String?
private var isPresented: Binding<Bool>?

// MARK: - Private Properties
private var subscription: AnyCancellable?

// MARK: - Lifecycle
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
presentAlertController()
}

private func presentAlertController() {
guard subscription == nil else { return } // present only once

let vc = UIAlertController(title: alertTitle, message: message, preferredStyle: .alert)

// add a textField and create a subscription to update the `text` binding
vc.addTextField { [weak self] textField in
guard let self = self else { return }
self.subscription = NotificationCenter.default
.publisher(for: UITextField.textDidChangeNotification, object: textField)
.map { ($0.object as? UITextField)?.text }
.assign(to: \.text, on: self)
}

// create a `Done` action that updates the `isPresented` binding when tapped
// this is just for Demo only but we should really inject
// an array of buttons (with their title, style and tap handler)
let action = UIAlertAction(title: "Done", style: .default) { [weak self] _ in
self?.isPresented?.wrappedValue = false
}
vc.addAction(action)
present(vc, animated: true, completion: nil)
}
}

2) TextFieldAlert wraps TextFieldAlertViewController using the UIViewControllerRepresentable protocol so that it can be used within SwiftUI.

struct TextFieldAlert {

// MARK: Properties
let title: String
let message: String?
@Binding var text: String?
var isPresented: Binding<Bool>? = nil

// MARK: Modifiers
func dismissable(_ isPresented: Binding<Bool>) -> TextFieldAlert {
TextFieldAlert(title: title, message: message, text: $text, isPresented: isPresented)
}
}

extension TextFieldAlert: UIViewControllerRepresentable {

typealias UIViewControllerType = TextFieldAlertViewController

func makeUIViewController(context: UIViewControllerRepresentableContext<TextFieldAlert>) -> UIViewControllerType {
TextFieldAlertViewController(title: title, message: message, text: $text, isPresented: isPresented)
}

func updateUIViewController(_ uiViewController: UIViewControllerType,
context: UIViewControllerRepresentableContext<TextFieldAlert>) {
// no update needed
}
}

3) TextFieldWrapper is a simple ZStack with a TextFieldAlert on the back (only if isPresented is true) and a presenting view on the front. The presenting view is the only one visibile.

struct TextFieldWrapper<PresentingView: View>: View {

@Binding var isPresented: Bool
let presentingView: PresentingView
let content: () -> TextFieldAlert

var body: some View {
ZStack {
if (isPresented) { content().dismissable($isPresented) }
presentingView
}
}
}

4) The textFieldAlert modifier allows us to smoothly wrap any SwiftUI view in a TextFieldWrapper and obtain the desired behaviour.

extension View {
func textFieldAlert(isPresented: Binding<Bool>,
content: @escaping () -> TextFieldAlert) -> some View {
TextFieldWrapper(isPresented: isPresented,
presentingView: self,
content: content)
}
}


Related Topics



Leave a reply



Submit