ビューコントローラ間でのデータの受け渡しに関する最初の質問
Aug 19 2020
iOSでNotesアプリを再作成しようとしています。単なるテーブルビューである最初のViewControllerを作成しました。ユーザーは、詳細ビューコントローラーに移動して、タイトルと本文のセクションを含む新しいメモを作成できます。彼らが[完了]をクリックしたときに、メモの詳細を使用してtableViewを操作したいと思います。
最初のViewControllerで使用するためにユーザーが入力した内容の詳細を保存するのに苦労しています。
これが、ノートデータを定義する私のNotesクラスです。
class Notes: Codable {
var titleText: String?
var bodyText: String?
}
これは、ユーザーがメモの詳細を入力できる詳細ビューコントローラーです。
class DetailViewController: UIViewController {
@IBOutlet var noteTitle: UITextField!
@IBOutlet var noteBody: UITextView!
var noteDetails: Notes?
var noteArray = [Notes]()
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(updateNote))
noteTitle.borderStyle = .none
}
@objc func updateNote() {
noteDetails?.titleText = noteTitle.text
noteDetails?.bodyText = noteBody.text
noteArray.append(noteDetails!) // This is nil
// not sure if this is the right way to send the details over
// let vc = ViewController()
// vc.noteArray.append(noteDetails!)
if let vc = storyboard?.instantiateViewController(identifier: "Main") {
navigationController?.pushViewController(vc, animated: true)
}
}
}
また、最初のViewControllerにも配列があります。tableViewに表示するメモデータを保存するためにこれが必要だと思います(そして、詳細ビューコントローラーに必要ないかもしれませんか?)。tableViewは明らかにまだ完全には実装されていません。
class ViewController: UITableViewController {
var noteArray = [Notes]()
override func viewDidLoad() {
super.viewDidLoad()
print(noteArray)
self.navigationItem.setHidesBackButton(true, animated: true)
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .compose, target: self, action: #selector(composeNote))
}
@objc func composeNote() {
if let dvc = storyboard?.instantiateViewController(identifier: "Detail") as? DetailViewController {
navigationController?.pushViewController(dvc, animated: true)
}
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
noteArray.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
return cell
}
回答
goat_herd Aug 19 2020 at 10:12
デリゲートを使用するだけ:最初に、関数を使用してデリゲートプロトコルを作成し、viewControllerにメモを送り返します
protocol DetailViewControllerDelegate: AnyObject {
func newNoteDidAdded(_ newNote: Note)
}
次に、デリゲート変数をDetailViewControllerに追加し、funcnoteDataDidUpdateを呼び出してデータをviewControllerに送り返します。
class DetailViewController: UIViewController {
weak var delegate: DetailViewControllerDelegate?
@objc func updateNote() {
....
delegate?.newNoteDidAdded(newNote)
}
}
最後に、デリゲート変数をviewControllerに設定し、これをViewControllerに実装します
class ViewController: UIViewController {
....
@objc func composeNote() {
if let dvc = storyboard?.instantiateViewController(identifier: "Detail") as? DetailViewController {
dvc.delegate = self
navigationController?.pushViewController(dvc, animated: true)
}
}
}
extension ViewController: DetailViewControllerDelegate {
func newNoteDidAdded(_ newNote: Note) {
// do some thing with your new note
}
}