Why are the buttons on my UIAlert duplicating?

Viewed 114

I'm attempting to build an app using Swift that's similar to the Notes app, but I'd like to have an Alert pop up when the user presses the "+" button to add a new Note - and the Alert would prompt the user to enter a name. The name is then added as a new row in the underlying table. So far, I've been able to do this, but every time i click the "+" sign, the buttons I've added to the Alert get re-added. In other words, the Alert should have an "OK" & a "Cancel" button. But on the 2nd time the Alert pops up, there are 2 "OK" buttons, and 2 "Cancel" buttons, and so on. Any ideas how i can fix this? Thanks for your help!

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

@IBOutlet weak var table: UITableView!

var data:[String] = []

//create alert controller
var alert = UIAlertController(title: "Name", message: "Enter a name", preferredStyle: .alert)



override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    self.title = "Notes"

    //create "add" button
    let addButton = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(addAlert))
    self.navigationItem.rightBarButtonItem = addButton
    //create edit button so we can delete rows
    self.navigationItem.leftBarButtonItem = editButtonItem
    load()

}

//function to add new note. This code is executed when the "Add" button is clicked

func addNote()
{
    //code to prevent being able to add rows while in edit mode
    if (table.isEditing) {
        return
    }

    let textField = self.alert.textFields![0] as UITextField
    let name:String = textField.text!
    data.insert(name, at: 0)
    let indexPath:IndexPath = IndexPath(row: 0, section: 0)
    table.insertRows(at: [indexPath], with: .automatic)
    save()
}

func addAlert()
{
    alert.addTextField(configurationHandler: { (textField) -> Void in
        textField.placeholder = "Enter Name"})
    self.present(alert, animated: true, completion: nil)
    //grab value from the text field and print when user clicks OK
    alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { (UIAlertAction) in
        let textField = self.alert.textFields![0] as UITextField
        print("Text Field: \(textField.text!)")
        self.addNote()
    }))
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return data.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell:UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "cell")!
    cell.textLabel?.text = data[indexPath.row]
    return cell
}

override func setEditing(_ editing: Bool, animated: Bool) {
    super.setEditing(editing, animated: animated)
    //puts table in edit mode
    table.setEditing(editing, animated: animated)
}

//function to delete rows from table
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
    data.remove(at: indexPath.row)
    table.deleteRows(at: [indexPath], with: .fade)
    save()
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    self.performSegue(withIdentifier: "detail", sender: nil)


}

func save()
{
    UserDefaults.standard.set(data, forKey: "notes")
    UserDefaults.standard.synchronize()
}

func load()
{
    if let loadedData = UserDefaults.standard.value(forKey: "notes") as? [String]
    {
        data = loadedData
        table.reloadData()
    }
}

enter image description here

enter image description here

2 Answers
Related