使用Xcode ver 9.2,Swift开发iOS应用程序。
当按下NavigationBar右上角的编辑按钮时,如何更改TableViewCell中的textField以使其可编辑? 为了防止在初始显示中编辑TextField,我使用TableViewCell.swift中的awakeFromNib()设置textField.isEnabled = false。 按下编辑按钮时,我想将其设置为true,以便我可以编辑TextField。 你能告诉我怎么样吗?
对象放置和代码(括号内)之间的关系如下。
NavigationController - TableViewController(TableViewController.swift) - TableViewCell(TableViewCell.swift) - TextField
这是代码。
TableViewController.swift
import UIKit
class TableViewController: UITableViewController, TableViewCellDelegate {
@IBOutlet var ttableView: UITableView!
var array:[String] = ["aaa", "bbb", "ccc", "ddd", "eee"]
override func viewDidLoad() {
super.viewDidLoad()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
self.navigationItem.rightBarButtonItem = self.editButtonItem
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func setEditing(_ editing: Bool, animated: Bool) {
super.setEditing(editing, animated: animated)
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return array.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "inputCell", for: indexPath) as! TableViewCell
cell.textField.text = array[indexPath.row]
cell.delegate = self
return cell
}
func textFieldDidEndEditing(cell: TableViewCell, value: String) -> () {
let path = tableView.indexPathForRow(at: cell.convert(cell.bounds.origin, to: tableView))
array[(path?.row)!] = value
}
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if (editingStyle == UITableViewCellEditingStyle.delete) {
array.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
}
}
override func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
let cell = tableView.cellForRow(at: sourceIndexPath) as! TableViewCell
let moveData = cell.textField.text
array.remove(at: sourceIndexPath.row)
array.insert(moveData!, at: destinationIndexPath.row)
}
}
TableViewCell.swift
import UIKit
protocol TableViewCellDelegate {
func textFieldDidEndEditing(cell: TableViewCell, value: String) -> ()
}
class TableViewCell: UITableViewCell, UITextFieldDelegate {
var delegate: TableViewCellDelegate! = nil
@IBOutlet weak var textField: UITextField!
override func awakeFromNib() {
super.awakeFromNib()
textField.delegate = self
textField.returnKeyType = .done
// To prevent the TextField from being edited in the initial display
textField.isEnabled = false
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
func textFieldDidEndEditing(_ textField: UITextField) {
self.delegate.textFieldDidEndEditing(cell: self, value: textField.text!)
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
}
我从第一次问题和答案中添加了以下内容。
Editing screen shot: after edit button is pressed
如果数组中有许多元素,则单元格将位于屏幕之外,但我也希望所有textField都可以编辑。
var array:[String] = ["aaa", "bbb", "ccc", "ddd", "eee", "fff", "ggg", "hhh", "iii", "jjj", "kkk", "lll", "mmm", "nnn", "ooo", "ppp", "qqq", "rrr", "sss", "ttt"]
Editing screen shot for many elements
最终解决了代码
TableViewController.swift
import UIKit
class TableViewController: UITableViewController, TableViewCellDelegate {
@IBOutlet var ttableView: UITableView!
// var array:[String] = ["aaa", "bbb", "ccc", "ddd", "eee"]
var array:[String] = ["aaa", "bbb", "ccc", "ddd", "eee", "fff", "ggg", "hhh", "iii", "jjj", "kkk", "lll", "mmm", "nnn", "ooo", "ppp", "qqq", "rrr", "sss", "ttt"]
override func viewDidLoad() {
super.viewDidLoad()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Edit", style: .plain, target: self, action: #selector(rightBarButtonItemTapped))
}
// handle tap by button...
@objc func rightBarButtonItemTapped(_ sender: UIBarButtonItem) {
ttableView.setEditing(!ttableView.isEditing, animated: true)
navigationItem.rightBarButtonItem?.title = ttableView.isEditing ? "Done" : "Edit"
navigationItem.rightBarButtonItem?.style = ttableView.isEditing ? .done : .plain
ttableView.visibleCells.forEach { cell in
guard let cell = cell as? TableViewCell else { return }
cell.textField.isEnabled = ttableView.isEditing
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return array.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "inputCell", for: indexPath) as! TableViewCell
cell.textField.text = array[indexPath.row]
cell.textField.isEnabled = tableView.isEditing
cell.delegate = self
return cell
}
func textFieldDidEndEditing(cell: TableViewCell, value: String) -> () {
let path = tableView.indexPathForRow(at: cell.convert(cell.bounds.origin, to: tableView))
array[(path?.row)!] = value
}
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if (editingStyle == UITableViewCellEditingStyle.delete) {
array.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
}
}
override func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
if tableView.isEditing {
return UITableViewCellEditingStyle.delete
} else {
return UITableViewCellEditingStyle.none
}
}
override func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
let cell = tableView.cellForRow(at: sourceIndexPath) as! TableViewCell
let moveData = cell.textField.text
array.remove(at: sourceIndexPath.row)
array.insert(moveData!, at: destinationIndexPath.row)
}
}
TableViewCell.swift
import UIKit
protocol TableViewCellDelegate {
func textFieldDidEndEditing(cell: TableViewCell, value: String) -> ()
}
class TableViewCell: UITableViewCell, UITextFieldDelegate {
var delegate: TableViewCellDelegate! = nil
@IBOutlet weak var textField: UITextField!
override func awakeFromNib() {
super.awakeFromNib()
textField.delegate = self
textField.returnKeyType = .done
//textField.isEnabled = false
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
func textFieldDidEndEditing(_ textField: UITextField) {
self.delegate.textFieldDidEndEditing(cell: self, value: textField.text!)
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
}
答案 0 :(得分:0)
首先,您应该处理导航按钮,找到textField
的单元格,然后设置textField.isEnabled = true
。
您可以这样做:
override func viewDidLoad() {
super.viewDidLoad()
// in your code `self.editButtonItem` is the `UIBarButtonItem`, so make sure that it configured properly
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .edit, target: self, action: #selector(rightBarButtonItemTapped))
}
// handle tap by button...
@objc func rightBarButtonItemTapped(_ sender: UIBarButtonItem) {
// and set `textField.isEnabled` to all `visibleCells`
ttableView.visibleCells.forEach { cell in
guard let cell = cell as? TableViewCell { else return }
cell.textField.isEnabled = true
}
// or set `isEnabled` to specific `textField` at index 0
if let cell = ttableView.cellForRow(at: IndexPath(row: 0, section: 0)) {
cell.textField.isEnabled = true
}
}
<强> UPD。强>
根据您的屏幕截图:
不需要设置textField.isEnabled = false
您只需要setEditing
用于tableView,并在导航栏中显示相应的按钮标题。
示例:
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Edit", style: .plain, target: self, action: #selector(rightBarButtonItemTapped))
}
@objc func rightBarButtonItemTapped(_ sender: UIBarButtonItem) {
ttableView.setEditing(!ttableView.isEditing, animated: true)
navigationItem.rightBarButtonItem?.title = ttableView.isEditing ? "Done" : "Edit"
navigationItem.rightBarButtonItem?.style = ttableView.isEditing ? .done : .plain
}
最后更新
好的,现在只有你应该做的步骤:
awakeFromNib
代码中删除禁用textField
cellForRowAtIndexPath
方法中写cell.textField.isEnabled = tableView.isEditing
UPD
代码textField
,您应该使用visibleCells
的原始答案(我更新了此部分,现在您不应该有任何错误)。请注意,此代码仅适用于当前可见的单元格。对于其他人来说它也有效,但set textField enabled
部分进入cellForRowAtIndexPath
方法,因为这些单元格将出现在屏幕上。 答案 1 :(得分:0)
您可以通过创建导航栏按钮项的操作来完成此操作,在该操作中,您只需启用textField,如下所示:
{{1}}