0

I am still new to swift and I would ask you for advice. Thank you in advance and sorry for my bad English.

My goal is:

User tap edit button in the table's row. UITextField appears instead cell. After entering value and pressing Return key UITextField disappears again and cell is recalculated.

editButton pressed -> hide priceCell & show UITextField & show keyboard & start editing/entering value (blinking cursor) -> stop editing/entering value execute by pressing Return key -> hide UITextField & shows priceCell & save entered value into array & reload edited row

I use this answer as starting blueprint.

I would like to also use .decimalPad keyboard to easier entering numeric value and limit user to use only numbers (and decimal point), but this exclude use Return key as stop editing, am I right?

I found this possible solution, but it seems to me complex for my problem...

my ViewController:

import UIKit

class PortfolioViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate, PortfolioCellDelegate {    

    let getData = GetData()

    ...

    override func viewDidLoad() {
        super.viewDidLoad()

        cellTableView.delegate = self
        cellTableView.dataSource = self

        cellTableView.register(UINib(nibName: "PortfolioCell", bundle: nil), forCellReuseIdentifier: "portfolioCell")

        self.currencyControl.selectedSegmentIndex = MyVariables.currencyControlSelected

    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let coinCell = tableView.dequeueReusableCell(withIdentifier: "portfolioCell", for: indexPath) as! PortfolioCell

        ...

        coinCell.delegate = self

        return coinCell
    }

    ...


    func portfolioButtonPressed(coinCell: PortfolioCell) {
        let indexPath = self.cellTableView.indexPathForRow(at: coinCell.center)!
        let selectedCell = cellTableView.cellForRow(at: indexPath) as! PortfolioCell

        selectedCell.priceCell.isHidden = true
        selectedCell.textCell.isHidden = false

        selectedCell.textCell.delegate = self

        func textFieldDidEndEditing(textField: UITextField) {
            let owned: Double = Double(textField.text!)!

            if owned >= 0 {
                MyVariables.dataArray[indexPath.row].ownedCell = owned
            } else {
                MyVariables.dataArray[indexPath.row].ownedCell = 0.00
            }

            selectedCell.priceCell.isHidden = false
            selectedCell.textCell.isHidden = true

            self.cellTableView.reloadData()
        }

        func textFieldShouldReturn(textField: UITextField) -> Bool {
            selectedCell.textCell.resignFirstResponder()
            return true
        }
    }
    ...
}

my custom cell:

import UIKit

protocol PortfolioCellDelegate {
    func portfolioButtonPressed(coinCell: PortfolioCell)
}

class PortfolioCell: UITableViewCell {

    var delegate: PortfolioCellDelegate?

    ...

    @IBAction func editCellPressed(_ sender: UIButton) {
     delegate?.portfolioButtonPressed(coinCell: self)
    }
    ...
}

enter image description here

For now when button is pressed proper UITextField shows, but don't dismiss after Return key is pressed.

Or should I change it completely and use tap gestures?

Riajur Rahman
  • 1,794
  • 17
  • 25
Jan Moravek
  • 13
  • 1
  • 3
  • Problem was that I did not declare `UITextField` delegate and I did not know that I can use `override func awakeFromNib() {...}` same as `override func viewDidLoad() {}` to declare delegates – Jan Moravek Dec 22 '17 at 18:44

5 Answers5

0

To end editing in any kind of scrollView, simply use this

cellTableView.keyboardDismissMode = .onDrag

or

cellTableView.keyboardDismissMode = .interactive

It will hide keyboard when you interact with the tableView

Tj3n
  • 9,054
  • 2
  • 19
  • 31
0

For number keypad you can add toolbar as a textField's inputAccessoryView. On toolbar add cancel button to dismiss keyboard.

Sneha
  • 34
  • 2
0

There is two way to go:

1.) Delegate 2.) IQKeyboardManager

1.) Use UITextFieldDelegate

There is one particular callback named "textFieldShouldEndEditing" In this method, return true.

2.) User the IQKeyboardManager one liner library. This library manages all the TextFields and scrollviews automatically. You activate it with one line in AppDelegate so it's easy to use.

https://github.com/hackiftekhar/IQKeyboardManager

Tomo Norbert
  • 691
  • 4
  • 12
  • I tried IQKeyboardManagerSwift. I followed the installation guide but toolbar did not show. But I definitely try use it in future again... – Jan Moravek Dec 22 '17 at 18:34
0

Working but not as sleek as want it to be and also I was not capable to make IQKeyboardManager works so I did use inputAccessoryView.

custom cell:

import UIKit

protocol PortfolioCellDelegate {
    func portfolioButtonPressed(didSelect coinCell: PortfolioCell)
    func portfolioButtonPressed(coinCell:PortfolioCell, editingChangedInTextCell newValue:String)
}

class PortfolioCell: UITableViewCell, UITextFieldDelegate  {

    var delegate: PortfolioCellDelegate?

    ...

    @IBAction func editCellPressed(_ sender: UIButton) {
        textCell.becomeFirstResponder()
        delegate?.portfolioButtonPressed(didSelect: self)
    }

    @IBAction func textCellValueChanged(_ sender: UITextField) {

        if (sender.text?.isEmpty)! {
            delegate?.portfolioButtonPressed(coinCell: self, editingChangedInTextCell: "XXX")
        } else {
            let text = sender.text
            delegate?.portfolioButtonPressed(coinCell: self, editingChangedInTextCell: text!)
        }
    }

    override func awakeFromNib() {
        super.awakeFromNib()

        self.textCell.delegate = self

        let flexiableSpace = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil)
        let doneButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.done, target: self, action: #selector(self.doneButtonAction))
        let toolBar:UIToolbar = UIToolbar(frame: CGRect(x: 0, y: 0, width: frame.size.width, height: 35))

        toolBar.barTintColor = UIColor(red:0.15, green:0.69, blue:0.75, alpha:1.0)
        toolBar.tintColor = UIColor(red:0.93, green:0.93, blue:0.93, alpha:1.0)
        toolBar.setItems([flexiableSpace, doneButton], animated: false)

        textCell.inputAccessoryView = toolBar
        textCell.keyboardType = UIKeyboardType.decimalPad
    }

    @objc func doneButtonAction() {
        textCell.endEditing(true)
    }

    ...       
}

ViewController:

import UIKit

class PortfolioViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, PortfolioCellDelegate {

    let getData = GetData()

    ...


    override func viewDidLoad() {
        super.viewDidLoad()        

        cellTableView.delegate = self
        cellTableView.dataSource = self

        cellTableView.register(UINib(nibName: "PortfolioCell", bundle: nil), forCellReuseIdentifier: "portfolioCell")

        self.currencyControl.selectedSegmentIndex = MyVariables.currencyControlSelected

        getData.delegate = self

        timeStampLabel.text = MyVariables.timeStamp
    }   

    override func viewDidAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        self.cellTableView.reloadData()
        self.currencyControl.selectedSegmentIndex = MyVariables.currencyControlSelected
        self.timeStampLabel.text = MyVariables.timeStamp
    }

    //MARK: - tableView
    /***************************************************************/

    ...


    func portfolioButtonPressed(coinCell: PortfolioCell, editingChangedInTextCell newValue: String) {
        let indexPath = self.cellTableView.indexPathForRow(at: coinCell.center)!
        let selectedCell = cellTableView.cellForRow(at: indexPath) as! PortfolioCell

        selectedCell.priceCell.isHidden = false
        selectedCell.textCell.isHidden = true

        if newValue != "XXX" {
            let owned: Double = Double(newValue)!
            MyVariables.dataArray[indexPath.row].ownedCell = owned
        }

        selectedCell.priceCell.isHidden = false
        selectedCell.textCell.isHidden = true

        self.cellTableView.reloadRows(at: [indexPath], with: .automatic)
    }

    func portfolioButtonPressed(didSelect coinCell: PortfolioCell) {
        let indexPath = self.cellTableView.indexPathForRow(at: coinCell.center)!
        let selectedCell = cellTableView.cellForRow(at: indexPath) as! PortfolioCell

        selectedCell.priceCell.isHidden = true
        selectedCell.textCell.isHidden = false
    }
        ...

}

Jan Moravek
  • 13
  • 1
  • 3
0

It's easy: You should select that table view cell, then enable User Interaction Enabled in the attribute inspector.

Saeed Ir
  • 1,021
  • 10
  • 15