0

I am trying to save values from a tableview that users will input into the textfield, the problem is that I do not know how to access the new value and replace the string in the array.

So basically the app will display fields based on what the user wants and then the user can edit those values to their liking. Once the textfields have been updated, the values are stored again in userdefaults so that the next time the tableview is opened, the update values will appear.

This is what the tableviewcontroller looks like at the moment:

//
//  Asset1TableViewController.swift
//  Net Calc 2
//
//  Created by Joshua Peterson on 30/06/2015.
//  Copyright © 2015 Peterson Productions. All rights reserved.
//

import UIKit

class Asset1TableViewController: UITableViewController {


var dataHolder: [NSString] = [NSString]()
var finalDataHolder: [NSString] = [NSString]()
var acountAmountHolder: [NSString] = [NSString]()
var finalAccountAmountHolder: [NSString] = [NSString]()

let defaults = NSUserDefaults.standardUserDefaults()
let key1 = "keySave1"
let key2 = "keySave2"


override func viewDidLoad() {
    super.viewDidLoad()

         dispatch_async(dispatch_get_main_queue(), { () -> Void in
        if let storedTitleValue : NSArray? = self.defaults.arrayForKey(self.key1) {

            if storedTitleValue == nil {
                self.dataHolder = [NSString]()
            } else {
            let readArray : [NSString] = storedTitleValue as! [NSString]


            for element in readArray {
                self.dataHolder.append(element as String)
                self.finalDataHolder.append(element as String)

            }
        }
    }

            if let storedAmountValue : NSArray? = self.defaults.arrayForKey(self.key2) {

                if storedAmountValue == nil {
                    self.acountAmountHolder = [NSString]()
                } else {
                    let readArray : [NSString] = storedAmountValue as! [NSString]


                    for element in readArray {
                        self.acountAmountHolder.append(element as String)
                        self.finalAccountAmountHolder.append(element as String)

                    }

                }
            }
         })
        }

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}


// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 1
}

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


override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("Account1Cell", forIndexPath: indexPath) as! Account1Cell

    cell.AccountLabel.text = dataHolder[indexPath.row] as String
    cell.AccountAmount.text = acountAmountHolder[indexPath.row] as String

    return cell
}


@IBAction func addButtonTapped(sender: AnyObject) {

    let newAccounTitle = "Account Name"
    let newAccountAmount = "R0.00"

    dataHolder.append(newAccounTitle)
    acountAmountHolder.append(newAccountAmount)

    tableView.reloadData()
    }

@IBAction func saveButtonTapped(sender: AnyObject) {

    // Save
    defaults.setObject(dataHolder as Array, forKey: key1)
    defaults.setObject(acountAmountHolder as Array, forKey: key2)

    defaults.synchronize()

    }

override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
    return true
}

override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
    if editingStyle == UITableViewCellEditingStyle.Delete {
        dataHolder.removeAtIndex(indexPath.row)
        acountAmountHolder.removeAtIndex(indexPath.row)
        tableView.deleteRowsAtIndexPaths([indexPath],  withRowAnimation: UITableViewRowAnimation.Automatic)
    }
}


/*
// Override to support rearranging the table view.
override func tableView(tableView: UITableView, moveRowAtIndexPath fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath) {

}
*/

/*
// Override to support conditional rearranging of the table view.
override func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool {
    // Return NO if you do not want the item to be re-orderable.
    return true
}
*/
}

I have tried to apply some of the code that i have found on the website but the problem is that I cant actually connect to the cell.

Ok so after some research I have added a few functions to the custom cell class so that it looks like this:

import UIKit

protocol TableViewCellDelegate {
  // Indicates that the edit process has begun for the given cell
  func cellDidBeginEditing(editingCell: Account1Cell)
  // Indicates that the edit process has committed for the given cell
  func cellDidEndEditing(editingCell: Account1Cell)
}

class Account1Cell: UITableViewCell,  UITextFieldDelegate {


@IBOutlet weak var AccountLabel: UITextField!
@IBOutlet weak var AccountAmount: UITextField!


var delegate: TableViewCellDelegate?


override func awakeFromNib() {
    super.awakeFromNib()
    // Initialization code
    AccountLabel.delegate = self

}

override func setSelected(selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)

    // Configure the view for the selected state
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
    // close the keyboard on Enter
    AccountLabel.resignFirstResponder()
    return false
}

func textFieldShouldBeginEditing(textField: UITextField) -> Bool {
    // disable editing of completed to-do items
    return true
}

func textFieldDidEndEditing(textField: UITextField) {

    if AccountLabel != nil {
        let newAccountLabel = AccountLabel.text

        print(newAccountLabel) // Prints out the new edited text!!!!!!!!
    }
    if delegate != nil {
        delegate!.cellDidEndEditing(self)
    }
}

func textFieldDidBeginEditing(textField: UITextField) {
    if delegate != nil {
        delegate!.cellDidBeginEditing(self)
    }
 }



}

Now what I need to do is either replace that value in the Array at the index (which i think is going to be rather complicated) or create some sort of loop that will read ALL the values and simply store all of the new values to UserDefaults. Maybe there is something else?

Any help is appreciated!!

7
  • Why do you have "func textFieldDidEndEditing(textField: UITextField!)" within your "@IBAction func saveButtonTapped" method? Commented Jul 1, 2015 at 15:15
  • @the_pantless_coder That was a snippet that I took from another post on Stackoverflow. I tried to edit it to fit what I have - but no success! Any ideas on what I could do? Commented Jul 1, 2015 at 16:22
  • try to take the "func textFieldDidEndEditing(textField: UITextField!) {.....}" section out of your "saveButtonTapped" and paste it as its own func. Then make sure your textFields have there delegates hooked up so it calls the relevent delegate functions. I am off for the night, will come back and check up tomorrow. Main thing I would do to trouble shoot, make sure the textField delegates are firing/hooked up. Then, when you can confirm it is working correctly. Use the value you get from the textField delegate and save that to where ever it is needed. Commented Jul 1, 2015 at 16:36
  • @the_pantless_coder thanks so much! I will try figure it out tonight and comment back to let you know if I make any progress. Commented Jul 1, 2015 at 17:01
  • @the_pantless_coder I have been trying combination after combination and still cant get anything right! I have found some information on the textdelegates but from what I can understand they are to be defined in the Custom cell class. Where you set the delegate to self. After that, Its hopeless for me! lol. I hope you can maybe find a solution!? Commented Jul 2, 2015 at 0:49

1 Answer 1

1

You should have a protocol in your custom cell like this, and call it when the text field in the cell gets modified:

protocol TableViewCellToTVController{
    func cellCurrentlyEditing(editingCell: Account1Cell) -> Int
}
....
func textFieldShouldReturn(textField: UITextField) -> Bool {
    // close the keyboard on Enter

    let myrow: Int? = self.delegate_special?.cellCurrentlyEditing(self)
    println("cellCurrentlyEditing got called from delegate" , myrow)

    AccountLabel.resignFirstResponder()
    return false
}

implement this function in tableviewcontroller to know which row got selected :

func cellCurrentlyEditing(editingCell: Account1Cell) -> Int{
    var rowNum = 0
    let indexP: NSIndexPath = tableView.indexPathForCell(editingCell)!
    rowNum = indexP.row
    return rowNum
}

also make your tableviewcontroller the delegate for each cell:

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("Account1Cell", forIndexPath: indexPath) as! Account1Cell

        cell.AccountLabel.text = dataHolder[indexPath.row] as String
        cell.AccountAmount.text = acountAmountHolder[indexPath.row] as String
        cell.delegate_special = self;
        return cell
    }
Sign up to request clarification or add additional context in comments.

2 Comments

I am not a professional by any means but if I am not mistaken - That is Objective C? Any ideas on how to implement your code in swift?
i fixed an error and checked it in my own tableview! in your custom Account1Cell use an extra protocol ( i called it TableViewCellToTVController) and make Asset1TableViewController the delegate for that protocol . Fire that protocol when you are done editing your textfield in the custom cell and you will get the row number by using tableView.indexPathForCell(editingCell)!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.