1

I am creating an app with one of the tab being a guestbook where users can write something. I use an UIAlertController to pop up a window with a textfield for entering name, and a textview for entering the message. I want to make the "Post" button disabled by default, then enable it after the name field has at least 2 characters and the message has at least 3 characters. I have achieved this by

#1: declare the "Post" UIAlertAction at the top

let saveAction = UIAlertAction(title:"Post", style: .default, handler: { (action) -> Void in print(data) })

The above line gives the error (Cannot use instance member 'data' within property initializer; property initializers run before self is available.)

#2: add this "Post" button in alert and making it disabled

alert.addAction(saveAction)
saveAction.isEnabled = false

#3 add two functions to detect how many words are in the textfield and textview, and if they meet the requirement, enable the "Post" button

func textViewDidChange(_ textView: UITextView) { //Handle the text changes here
    GuestbookContentWordCount = textView.text.count
    data["content"] = textView.text
    enableSave()
    }
@objc func textFieldDidChange(_ textField: UITextField) {
    GuestbookNameWordCount = textField.text?.count ?? 0
    data["name"] = textField.text
    enableSave()
}
func enableSave () {
    if GuestbookContentWordCount >= 3 && addGuestbookNameWordCount >= 2 {
        saveAction.isEnabled = true
    } else {
        saveAction.isEnabled = false
    }
}

The ideal situation is when the requirements are met and the user clicks on the "Post" button, I will get the data["name"] and data["content"] and insert it into a database. Right now I have gotten it to work to the point that the "Post" button is enabled after the requirements are met, but when trying to get the data it gives the error "Cannot use instance member 'data' within property initializer; property initializers run before self is available.

Can you please advise how to solve this problem? Thank you.

enter image description here

enter image description here

Gino
  • 61
  • 1
  • 7
  • Can you provide your entire code? Specifically your code where you're retrieving the data? – Ameya Vichare Mar 18 '21 at 04:45
  • for data, I first declared one line 38 var data = [String:String]() Then I add the data in the two functions in the original post (textViewDidChange, textFieldDidChange): Line 122: data["content"] = textView.text Line128: data["name"] = textField.text I have added one more image with more of my code – Gino Mar 18 '21 at 05:22

1 Answers1

1

So this is what I would do

Change your UIAlertAction reference to this outside the viewDidLoad()

var saveAction: UIAlertAction? = nil

Inside the viewDidLoad() you can instantiate it like:

saveAction = UIAlertAction(title:"Post", style: .default, handler: { [weak self] (action) -> Void in
    guard let `self` = self else { return }
    print(self.data) }
)

[weak self] is used so that you don't end up having retain cycles after your UIViewController is deinitialised.

Ameya Vichare
  • 1,119
  • 1
  • 10
  • 22