Struggling to add multiple text fields to alertview

1.6k Views Asked by At

I'm trying to create an alert view that adds an item or items to my table view after taping an ad button. On pressing the add button the alertview should appear with three text fields for item name price and quantity and when pressing the ok button it will then add the item, however many times the quantity is. When I tap the button though I get the following error:

Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArray0 objectAtIndex:]: index 0 beyond bounds for empty NSArray'

Here are the functions:

func createAlertView() -> UIAlertController {

    let view = UIView(frame: CGRect(x: CGFloat(0), y: CGFloat(0), width: CGFloat(250), height: CGFloat(100)))
    let itemName = UITextField(frame: CGRect(x: CGFloat(10), y: CGFloat(0), width: CGFloat(252), height: CGFloat(25)))
    itemName.borderStyle = .RoundedRect
    itemName.placeholder = "Item Name"
    itemName.keyboardAppearance = .Alert
    itemName.delegate = self
    view.addSubview(itemName)

    let itemPrice = UITextField(frame: CGRect(x: CGFloat(10), y: CGFloat(30), width: CGFloat(252), height: CGFloat(25)))
    itemPrice.placeholder = "Item Price"
    itemPrice.borderStyle = .RoundedRect
    itemPrice.keyboardAppearance = .Alert
    itemPrice.delegate = self
    view.addSubview(itemPrice)

    let itemQuantity = UITextField(frame: CGRect(x: CGFloat(10), y: CGFloat(60), width: CGFloat(252), height: CGFloat(25)))
    itemQuantity.placeholder = "Item Quantity"
    itemQuantity.borderStyle = .RoundedRect
    itemQuantity.keyboardAppearance = .Alert
    itemQuantity.delegate = self
    view.addSubview(itemQuantity)

    let alertController = UIAlertController(title: "Add Item", message: nil, preferredStyle: .Alert)
    alertController.view.addSubview(view)

    return alertController
}

func createAlertViewItem(alertController: UIAlertController, itemName: String, itemStringPrice: String) {

    let managedContext = self.bill.managedObjectContext
    let entity = NSEntityDescription.entityForName("Item", inManagedObjectContext: managedContext!)
    let newItem = NSManagedObject(entity: entity!, insertIntoManagedObjectContext: managedContext)

    if let itemName = alertController.textFields?.first?.text {

        newItem.setValue(itemName, forKey: "name")

    }
    if let itemPriceString = alertController.textFields?[1].text {

        let itemPriceNumber = Int(itemPriceString)

        newItem.setValue(itemPriceNumber, forKey: "price")
    }

    do {
        try managedContext!.save()
    }
    catch let error as NSError {
        print("Core Data save failed: \(error)")
    }

    let currentItems = self.bill.mutableSetValueForKey("items")
    currentItems.addObject(newItem)

    self.tableView.reloadData()
}

@IBAction func addNewItem(sender: UIButton) {

    let alertController = createAlertView()

    let itemName = alertController.textFields![0].text
    let itemPrice = alertController.textFields?[1].text
    let itemQuantity: Int!

    if alertController.textFields![2].text == "" {
        itemQuantity = 0
    } else {
        itemQuantity = Int((alertController.textFields?[2].text)!)!
    }

    let okAction = UIAlertAction(title: "OK", style: .Default, handler: { (action) -> Void in
        if itemQuantity == 0 || itemQuantity == 1 {
            print(2)
            self.createAlertViewItem(alertController, itemName: itemName!, itemStringPrice: itemPrice!)
        } else {
            for _ in 0...itemQuantity {
                print(3)
                self.createAlertViewItem(alertController, itemName: itemName!, itemStringPrice: itemPrice!)
            }
        }
    })

    alertController.addAction(okAction)

    let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel, handler: nil)
    alertController.addAction(cancelAction)

    presentViewController(alertController, animated: true, completion: nil)
}

I think I'm missing something when adding the view to the alert view but I can't see what as I think the error is stating that it can't find the textfields. I can't be sure though. Any help would be great though. Thanks!

2

There are 2 best solutions below

1
On

You should not try to manaipulate the alert controller's view hierarchy. Instead, use the method addTextField(configurationHandler:) to add text fields to your alert controller. I suggest taking a look at the UIAlertController Class reference in Xcode. It is well documented.

EDIT:

Also, I would suggest not referring to a UIAlertController as an "alertview". In previous versions of iOS we used a class called a UIAlertView, but that's now deprecated. The term "alertview" is going to make people think you're using the old deprecated class.

0
On

Have you seen these other SO Questions? If so try to extrapolate. The error message seems to indicate a nil object between your method calls so make sure you are using a shared reference between these methods. Check the object values before and after adding the UITextfield to validate the state of the controller. Add your alertController as a reference to your UIViewController class and check its state when you make the desired changes.