どのように作るか次第ですが、たぶん UITextField の処理で混乱されているように思えます。
Swift
1class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate {
2 // 中略
3 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
4 let cell: TaskCell = tableView.dequeueReusableCell(withIdentifier: "TaskCell", for: indexPath) as! TaskCell
5 cell.taskTextField.delegate = self
6 }
7}
上記のコードでは、
Swift
1cell.taskTextField.delegate = self
と、Delegate に ViewController
のインスタンスを入れていますが、そうではなくて、UITableViewCell
のインスタンスを代入し、セルの中で処理を行ったほうが簡潔に書けそうな気がします。
つまり、
Swift
1class TaskCell: UITableViewCell, UITextFieldDelegate {
カスタムセルに UITextFieldDelegate
を準拠させ、
Swift
1 private lazy var textField: UITextField = {
2 let tf = UITextField()
3 tf.borderStyle = .line
4
5 // ここの self は UITableViewCell 自身
6 tf.delegate = self
7
8 return tf
9 }()
UITableViewCell 内部の UITextField の delegate
はセル自身にした上で
Swift
1
2 func textFieldShouldReturn(_ textField: UITextField) -> Bool {
3 label.text = textField.text
4 textField.text = ""
5 task?.taskName = textField.text ?? ""
6 textField.resignFirstResponder()
7
8 return true
9 }
セルの中で UITextFiled の処理を行うといった感じです。
たとえば、こんな感じです(StoryBoard は使っていなので、このままコピーてして実行すると動くと思います)。
Swift
1import UIKit
2
3class Task {
4 var taskName: String
5
6 init(taskName: String) {
7 self.taskName = taskName
8 }
9}
10
11class TaskCell: UITableViewCell, UITextFieldDelegate {
12 private var task: Task?
13
14 override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
15 super.init(style: style, reuseIdentifier: reuseIdentifier)
16
17 setUp()
18 }
19
20 required init?(coder: NSCoder) {
21 fatalError("init(coder:) has not been implemented")
22 }
23
24 private let label = UILabel()
25
26 private lazy var textField: UITextField = {
27 let tf = UITextField()
28 tf.borderStyle = .line
29
30 // ここの self は UITableViewCell 自身
31 tf.delegate = self
32
33 return tf
34 }()
35
36 private lazy var button: UIButton = {
37 let b = UIButton(type: .system)
38 b.setTitle("set", for: .normal)
39 b.backgroundColor = .yellow
40 b.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
41
42 return b
43 }()
44
45 // ボタンが押されたら、ラベルに UITextField の内容を表示し、UITextFiled は空にし、キーボードを閉じる
46 @objc private func buttonTapped(_ sender: UIButton) {
47 textField.resignFirstResponder()
48 label.text = textField.text
49 task?.taskName = textField.text ?? ""
50 textField.text = ""
51 }
52
53 // コードでカスタムセルを作成しているだけ。
54 private func setUp() {
55 let sv = UIStackView(arrangedSubviews: [label, textField, button])
56 contentView.addSubview(sv)
57 sv.axis = .vertical
58 sv.spacing = 6
59
60 sv.translatesAutoresizingMaskIntoConstraints = false
61 sv.topAnchor.constraint(equalTo: self.contentView.layoutMarginsGuide.topAnchor).isActive = true
62 sv.leadingAnchor.constraint(equalTo: self.contentView.layoutMarginsGuide.leadingAnchor).isActive = true
63 sv.trailingAnchor.constraint(equalTo: self.contentView.layoutMarginsGuide.trailingAnchor).isActive = true
64 sv.bottomAnchor.constraint(equalTo: self.contentView.layoutMarginsGuide.bottomAnchor).isActive = true
65 }
66
67 // セルに各要素をセット
68 func setItem(_ task: Task) {
69 self.task = task
70 label.text = task.taskName
71 textField.text = ""
72 }
73
74 // セルの中で UITextFiled の処理を行う
75 func textFieldShouldReturn(_ textField: UITextField) -> Bool {
76 label.text = textField.text
77 textField.text = ""
78 task?.taskName = textField.text ?? ""
79 textField.resignFirstResponder()
80
81 return true
82 }
83}
84
85class ViewController: UIViewController {
86 var data = (1...10).map { _ in Task(taskName: "not set") }
87
88 lazy var tableView: UITableView = {
89 let tv = UITableView(frame: CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.size.height))
90 tv.dataSource = self
91 tv.delegate = self
92
93 tv.register(TaskCell.self, forCellReuseIdentifier: "cell")
94
95 return tv
96 }()
97
98 override func viewDidLoad() {
99 super.viewDidLoad()
100 // Do any additional setup after loading the view.
101
102 view.addSubview(tableView)
103 }
104}
105
106extension ViewController: UITableViewDelegate, UITableViewDataSource {
107 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
108 return data.count
109 }
110
111 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
112 let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TaskCell
113
114 cell.setItem(data[indexPath.row])
115
116 return cell
117 }
118}
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/02/01 13:33
2021/02/01 13:39