48079


はじめまして。プログラミング初心者です。初めての投稿です。  
SwiftにてUiTableViewを用いている場合のデータの取得に関する質問です。

すこし説明しにくいので、実例を用いてみます。

iPhoneのカレンダーのアプリにて新しいイベントを作成するページにある機能なのですが、イベントの繰り返しを変更する際に、ディフォルトのNeverをタップすると新しいページが開きます。  
そのぺージにて選択を変更すると、選択されたセルのデータが次のページにて表示されます。

これはどのように設定すればよいのでしょうか。

セグエでもなさそうですし、セルにはUILabelではなく UItextviewを用いるのではと思いますが、どのようにデータを扱うのかよくわかりません。

また、選択したセルのデータをどのように取得し、どのタイミングで最初のページに転送しているのかも不明です。  
以下にてスクリーンショットを添付します。  
サンプルのコードを頂ければ助かります。  
お手数ですが、よろしくお願いします。

![画像の説明をここに入力](https://i.stack.imgur.com/oCZij.jpg)  
![画像の説明をここに入力](https://i.stack.imgur.com/tl439.jpg)  
![画像の説明をここに入力](https://i.stack.imgur.com/ZvHVs.jpg)


CC BY-SA 4.0
2018-09-04T08:11:59.753
48073
2018-09-04T11:56:45.287
29970
question
ios swift4
Swift UITableViewにて、前画面にて選択されたデータの取得


こんばんは。Qiita でもコメントさせていただいた者です。

さて、この

> タップすると新しいページが開きます。そのぺージにて選択を変更すると、選択されたセルのデータが次のページにて表示されます。

というのは、「画面遷移した先でデータを選択し、遷移元の表示も変える」と言い表すことができるでしょう。

では、遷移元を `MainTableViewController` 、遷移先を `DetailTableViewController`
としてサンプルを示します（画像ではなく文章を書き連ねています…）。  
どちらも `UITableViewController` を継承しています。

`MainTableViewController.swift`

[code]

    import UIKit
    
    class MainTableViewController: UITableViewController {
    
        var detailText = "初期値"
    
        override func viewDidLoad() {
            super.viewDidLoad()
        }
    
        override func viewWillAppear(_ animated: Bool) {
            self.tableView.reloadData()
            super.viewWillAppear(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 1
        }
    
        override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
    
            // Configure the cell...
            cell.textLabel?.text = "項目のなまえ"
            cell.detailTextLabel?.text = self.detailText
    
            return cell
        }
    
        // MARK: - Navigation
    
        // In a storyboard-based application, you will often want to do a little preparation before navigation
        override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
            // Get the new view controller using segue.destinationViewController.
            // Pass the selected object to the new view controller.
            if segue.identifier == "toDetail" {
                let detailVC = segue.destination as! DetailTableViewController
                detailVC.mainVC = self
            }
        }
    
    }
    
[/code]

`DetailTableViewController.swift`

[code]

    import UIKit
    
    class DetailTableViewController: UITableViewController {
    
        var mainVC: MainTableViewController!
        let list = ["今日だけ", "明日だけ", "毎日"]
    
        override func viewDidLoad() {
            super.viewDidLoad()
        }
    
        // 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 3
        }
    
        override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
    
            // Configure the cell...
            cell.textLabel?.text = self.list[indexPath.row]
    
            return cell
        }
    
        override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
            self.mainVC.detailText = self.list[indexPath.row]
            self.tableView.deselectRow(at: indexPath, animated: true)
        }
    }
    
[/code]

`Storyboard` では `UINavigationController` を Initial View Controller に設定し、その
`rootViewController` に `MainTableViewController` を、指定します。

`MainTableViewController` も `DetailTableViewController` も Table View のContent
は Dynamic Prototypes とし、Prototype Cells は1つで、その Table View Cell の Style は
Right Detail、Identifier は `cell` としました。

`MainTableViewController` の `cell` から `DetailTableViewController` まで Segue
を引き、その Identifier は `toDetail` とします。

さて、`MainTableViewController` から説明します。  
あらかじめ `detailText` 変数を記述しておき、とりあえず `初期値` としました。  
そして、 `tableView(_:cellForRowAt:)` でそれぞれ代入するようにしています。

`Storyboard` で Segue を設定したので、 `prepare(for:sender:)` で `segue.identifier` が
`toDetail` だったとき、遷移先の `DetailTableViewController` の `mainVC`
変数に自身のインスタンスを代入します。

次に `DetailTableViewController` です。  
`mainVC` 変数に `MainTableViewController` のインスタンスが入ることになります。  
選択肢を今回は3つ、「今日だけ、明日だけ、毎日」を用意しました。  
ポイントは `tableView(_:didSelectRowAt:)` 内です。  
選択したセルの `indexPath.row` に応じて `list` 配列の1つを取り出し、  
`self.mainVC.detailText` に代入することで遷移元の `MainTableViewController` インスタンスの
`detailText` に代入しています。  
（今回はタップによってチェックマークが表示されたり消えたりという動作は省略しています。）

`MainTableViewController` に戻りまして、  
`viewWillAppear(_:)` で `self.tableView.reloadData()` を呼びます。  
すると `初期値` と表示されていた部分が遷移先で選択したものに表示が変わっているかと思います。

* * *

今回は簡単なサンプルということで以上のようなコードを書きましたが、実際のところは `Unwind Segue` を使ったり、Table View
の更新も工夫が必要になってくるかと思います。

これから Swift、iOS、そして質問の仕方等、様々学ばれていくことを期待しています！


CC BY-SA 4.0
2018-09-04T11:56:45.287
48079
2018-09-04T11:56:45.287
10947
48073
answer