UITextField 不会在 Swift 4 的 UITableViewCell 中结束编辑
UITextField doesn't end editing in a UITableViewCell in Swift 4
我还是 swift 的新手,我想请教您。提前谢谢你,抱歉我的英语不好。
我的目标是:
用户点击 table 行中的编辑按钮。 UITextField
出现而不是单元格。输入值并按下 Return
键后,UITextField
再次消失并重新计算单元格。
editButton
pressed -> hide priceCell
& show UITextField
& show keyboard & start editing/entering value (blinking cursor) -> 停止 editing/entering 值按 Return
键执行 -> 隐藏 UITextField
& 显示 priceCell
& 将输入的值保存到数组中 & 重新加载编辑的行
我使用 答案作为起始蓝图。
我也想使用 .decimalPad
键盘来更容易地输入数值并限制用户只能使用数字(和小数点),但这不包括使用 Return
键作为停止编辑,我我对吗?
我找到了 this 可能的解决方案,但对我来说这对我的问题来说似乎很复杂...
我的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
}
}
...
}
我的自定义单元格:
import UIKit
protocol PortfolioCellDelegate {
func portfolioButtonPressed(coinCell: PortfolioCell)
}
class PortfolioCell: UITableViewCell {
var delegate: PortfolioCellDelegate?
...
@IBAction func editCellPressed(_ sender: UIButton) {
delegate?.portfolioButtonPressed(coinCell: self)
}
...
}
现在,当正确按下按钮时 UITextField
显示,但在按下 Return
键后不要关闭。
或者我应该完全改变它并使用点击手势吗?
要在任何类型的滚动视图中结束编辑,只需使用这个
cellTableView.keyboardDismissMode = .onDrag
或
cellTableView.keyboardDismissMode = .interactive
当您与 tableView 交互时,它会隐藏键盘
对于数字小键盘,您可以将工具栏添加为文本字段的 inputAccessoryView。在工具栏上添加取消按钮以关闭键盘。
有两条路可走:
1.) 代表
2.) IQKeyboardManager
1.)
使用 UITextFieldDelegate
有一个特定的回调名为 "textFieldShouldEndEditing"
在这个方法中,return true.
2.)
使用 IQKeyboardManager 一个线性库。这个库自动管理所有的 TextFields 和 scrollviews。您只需在 AppDelegate 中使用一行即可激活它,因此它易于使用。
可以工作,但不如希望的那样圆滑,而且我无法使 IQKeyboardManager
工作,所以我确实使用了 inputAccessoryView
。
自定义单元格:
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
}
...
}
很简单:您应该select那个table查看单元格,然后在属性检查器中启用启用用户交互。
我还是 swift 的新手,我想请教您。提前谢谢你,抱歉我的英语不好。
我的目标是:
用户点击 table 行中的编辑按钮。 UITextField
出现而不是单元格。输入值并按下 Return
键后,UITextField
再次消失并重新计算单元格。
editButton
pressed -> hide priceCell
& show UITextField
& show keyboard & start editing/entering value (blinking cursor) -> 停止 editing/entering 值按 Return
键执行 -> 隐藏 UITextField
& 显示 priceCell
& 将输入的值保存到数组中 & 重新加载编辑的行
我使用
我也想使用 .decimalPad
键盘来更容易地输入数值并限制用户只能使用数字(和小数点),但这不包括使用 Return
键作为停止编辑,我我对吗?
我找到了 this 可能的解决方案,但对我来说这对我的问题来说似乎很复杂...
我的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
}
}
...
}
我的自定义单元格:
import UIKit
protocol PortfolioCellDelegate {
func portfolioButtonPressed(coinCell: PortfolioCell)
}
class PortfolioCell: UITableViewCell {
var delegate: PortfolioCellDelegate?
...
@IBAction func editCellPressed(_ sender: UIButton) {
delegate?.portfolioButtonPressed(coinCell: self)
}
...
}
现在,当正确按下按钮时 UITextField
显示,但在按下 Return
键后不要关闭。
或者我应该完全改变它并使用点击手势吗?
要在任何类型的滚动视图中结束编辑,只需使用这个
cellTableView.keyboardDismissMode = .onDrag
或
cellTableView.keyboardDismissMode = .interactive
当您与 tableView 交互时,它会隐藏键盘
对于数字小键盘,您可以将工具栏添加为文本字段的 inputAccessoryView。在工具栏上添加取消按钮以关闭键盘。
有两条路可走:
1.) 代表 2.) IQKeyboardManager
1.) 使用 UITextFieldDelegate
有一个特定的回调名为 "textFieldShouldEndEditing" 在这个方法中,return true.
2.) 使用 IQKeyboardManager 一个线性库。这个库自动管理所有的 TextFields 和 scrollviews。您只需在 AppDelegate 中使用一行即可激活它,因此它易于使用。
可以工作,但不如希望的那样圆滑,而且我无法使 IQKeyboardManager
工作,所以我确实使用了 inputAccessoryView
。
自定义单元格:
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
}
...
}
很简单:您应该select那个table查看单元格,然后在属性检查器中启用启用用户交互。