質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

91.25%

  • Swift

    5330questions

    Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

  • データベース

    564questions

    データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

  • TableView

    65questions

    TableView(UITableView)とは、リスト形式で表示するコントロールで、ほとんどのアプリに使用されています。画面を「行」に分けて管理し、一般的には各行をタップした際に詳細画面に移動します。

[Swift]階層構造のデータについて、画面をまたいでのデータの受け渡しはどのようにしたらいいか

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 101

koshira27

score 1

やろうとしていること(ToDoアプリの画面まで作成)

SwiftでXcodeを使い簡単なToDoアプリを作っています。
作りとしては、よくある[一覧⇄リスト]の形のToDoリストアプリで、[ToDoリスト一覧]画面のToDoリスト一覧からToDoリストをタッチすると、[ToDoリスト]画面で該当するToDoリストのToDoの確認とチェックができるというものです。

[ToDoリスト一覧]画面と[ToDoリスト]画面はどちらもテーブルビューで作っており、それぞれの画面はテーブルビューで作成済みです。ストーリーボードは以下の通り。
イメージ説明

あとは、[ToDoリスト一覧]画面で選択したToDOリストのToDoを[ToDoリスト]画面で表示させる処理を実装すればいいのですが、画面をまたいでのデータの受け渡しをどうするかがわかりません。

お聞きしたいこと(画面をまたいでのデータの受け渡しはどのようにしたらいいかがわからない)

お聞きしたい点は、階層構造のデータについて、画面をまたいでのデータの受け渡しはどのようにしたらいいかです。

Swiftの本を読んだりネットで調べたりしたところ、画面をまたいでデータをやりとりする方法は主に下記の3つの方法があるようですが、下記それぞれについて具体的なコードや設定等の実装方法や参考となる書籍やURLを教えていただけると助かります。また、それぞれについて階層構造のデータのやり取りができるかも教えていただけると幸いです。

①AppDelegateに共有するデータを設定して、データの受け渡しを行う
②SharedInstanceを利用して共有オブジェクトとパラメータを保持する
③CoreData、RealmなどのモバイルDBを利用して画面と別のDBからデータを引っ張ってくる

なお、本やネット以外の方法として、
2階層なのでUITableViewプロトコルのセクションとセルのデータ構造を画面間で共有してデータを引っ張ってくる([ToDoリスト一覧]はセクション、[ToDoリスト]画面はセルを表示する仕組み)作りにしてもいいのではないかと自分なりに考えたのですが、UITableViewプロトコルの中のデータを2つの画面で共有することはできるのでしょうか?

長くて分かりにくい文章ですみませんがよろしくお願いします。

開発環境

Swift4
Xcode9.2

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • fuzzball

    2017/12/28 09:19

    受け渡しのことは置いておいて、そもそもデータはどうやって保存しているのでしょうか?

    キャンセル

  • koshira27

    2017/12/29 04:29

    現在各ビューの操作はuserDefaultsでデータを保存して行っていますが、データの受け渡し方法や今後のことを考えて修正する必要があると考えています。

    キャンセル

回答 1

checkベストアンサー

+1

やりやすくToDoListクラスなるものを作成して

class ToDoList: NSObject {
  var title: String?
  var content: String?
}

Todo一覧のViewController側で、データを格納させるための配列(todoListDataSource)を作成し、その中のrow番目のtoDoListを詳細側で渡せばいいのではないでしょうか?ちょっと雑にバーっと書きました
ただカスタムクラス(この場合ToDoListクラス)をUserDefaultで管理するのは少しめんどくさいので、この方法だとすんなりいかないかもしれませんが、応用はできるとは思います。(Realmとかだったら使いやすいと思いますし)

class ToDoListViewController {

 var todoListDataSource: [TodoList] ?

 func viewDidLoad() {
  super.viewDidLoad()
  getData()
 }

 func getData() {
  //ここで、todoListDataSourceに格納するコードをかく。
 }

}

.....

func func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

 let todoDetailVC = ToDetailViewController()
 //ここで遷移先のViewControllerにtoDoListを渡す
 toDodeitalVC.toDoList = todoListDataSource[indexPath.row]
 //遷移先のコードをかく
 (例)
 navigationController?.pushViewController(todoDetailVC, animated: true)
}

toDoList使える↓

class ToDoDetailViewController: UIViewController {

 var toDoList: ToDoList!

 func viewDiDLoad() {
  super.viewDidLoad()
 }
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/01/01 02:15 編集

    回答ありがとうございます!
    冒頭のToDoListクラスのコードはAppDelegate.swiftに書くということですよね?

    まだ実装できていないですが、画面をまたいでのデータの引き渡し方についてなんとなく方向性がわかった気がします。


    重ねて一点お聞きしたいのですが、ToDoリスト名とそれに紐づくToDo一覧の階層構造のデータ構造はどのようにしたらいいでしょうか?
    考えている処理は、任意の配列名AAA(ToDoリスト名)を追加、配列名AAA.appendで要素(ToDo)を追加していく処理を考えていましたが、もっとシンプルな方法はありますでしょうか?
    記載いただいたToDoListクラスの変数titleと変数contetの箇所の詳細部分にあたるのかもしれません。

    わかりにくい文章ですみません。
    下記のようなデータ構造をイメージしています。

    AAA
     aaa
     bbb
     ccc

    BBB
     ddd
     eee
     fff
     ggg

    キャンセル

  • 2018/01/01 21:56 編集

    ToDoListクラスは、New fileをしてもらって、別途ToDoList.swiftファイルを作る方がいいですね。appDelegateに書くこともできなくはないですが、それだと可読性が悪いです。二番目に関しての質問ですが、ある一つのToDoListに対して、いくつものToDoがぶら下がっているというイメージですが?

    ```
    class ToDoList: NSObject {

    var detailLists: [[ToListDetail]]?

    }

    ```

    ```
    class ToDoDetail: NSObject {

    var title: String?
    var content: String?
    var date: Date?
    }
    ```
    のようなイメージですかね

    キャンセル

  • 2018/01/01 21:31 編集

    コメントありがとうございます。
    ToDoListクラスは、別途ToDoList.swiftファイルを作るんですね。確かにその方がデータ部分のみモジュール化されて可読性と使い勝手がよさそうです。

    二番目の質問は、コメントいただいた通り、ある一つのToDoListに対して、いくつものToDoがぶら下がっているというイメージで合っています。上記の質問後に多次元配列という方法もあるかな〜と思いつきました。

    ちなみに、記載いただいたコードイメージのToDoListクラス内の変数とToDoDetailクラスの変数はデータの紐付けはできないように思えたのですが、紐付けできる想定でしょうか?Swift上のデータの取り扱いについてはほぼ初体験のため的外れな質問でしたらすみません。

    キャンセル

  • 2018/01/02 11:40 編集

    方法はいくらでもあるとは思うんですが、上の例でいくと
    生成したい箇所で、

    let toDoList = ToDoList()
    //二次元配列 (配列の配列)
    let toDoListDetailsArray = [[ToDoDetai]]()

    //一個目の配列
    let firstToDoDetailArray = [ToDoDetail]()

    let firstDetail = ToDoDetail()
    fristDetail.title = "frist"
    fristDetail.content = "first"
    firstToDoDetailArray.append(fristDetail)

    let secondDetail = ToDoDetail()
    secondDetail.title = "second"
    secondDetail.content = "second"
    firstToDoDetailArray.append(secondDetail)

    //toDoListDetailsArrayに一個目の配列を格納
    toDoListDetailsArray.append(firstToDoDetailArray)

    //二個目の配列
    let secondToDoDetailArray = [ToDoDetail]()

    let thirdDetail = ToDoDetail()
    thirdDetail.title = "frist"
    thirdDetail.content = "first"
    secondToDoDetailArray.append(thirdDetail)

    let fourthDetail = ToDoDetail()
    fourthDetail.title = "second"
    fourthDetail.content = "second"
    secondToDoDetailArray.append(fourthDetail)

    //toDoListDetailsArrayに二個目の配列を格納
    toDoListDetailsArray.append(secondToDoDetailArray)

    //toDoListのdetailListsプロパティにtoDoListDetailsArrayを入れる
    toDoList.detailLists = toDoListDetailsArray



    コード少し長くて汚いんですが、イメージ掴んでもらうためにあえて長くしました.
    おそらく二次元配列で解決するのではと思います。ToDoDetailクラスに関しても、ToDoDetail.swiftファイルを作成してください

    キャンセル

  • 2018/01/02 22:17

    回答ありがとうございます!

    いただいたアイディアを参考にして実装してみます。
    ベストアンサーをkomo_taさんにしました。

    キャンセル

  • 2018/01/02 23:21

    ありがとうございます。よろしくお願いします〜

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

ただいまの回答率

91.25%

関連した質問

同じタグがついた質問を見る

  • Swift

    5330questions

    Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

  • データベース

    564questions

    データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

  • TableView

    65questions

    TableView(UITableView)とは、リスト形式で表示するコントロールで、ほとんどのアプリに使用されています。画面を「行」に分けて管理し、一般的には各行をタップした際に詳細画面に移動します。