0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

View間でのDelegateのパターン。またNavigationLinkを使ったページ遷移のサンプルを作った。

Last updated at Posted at 2020-11-05

ViewDelegatePattern(つい習慣でViewControllerって書いちゃったけど名前的にはこっちの方がいい)

View間でのDelegateのパターン。またNavigationLinkを使ったページ遷移のサンプルにもなっている。

レポジトリはここ>https://github.com/dropcontrol/ViewControllerDelegatePattern
この記事自体もレポジトリのREADME.mdと同じ。

TL;DR

View間で値を渡すパターン。Viewを二つ用意。親から子へ渡すパターンと、子から親へ渡すパターンの2つを実装。値の渡し方は他にもあると思うけど、一番基本的なパターン。

親から子へ渡す場合

子であるSecondView.swiftに以下を追加

let text: String = "Not Success" // 初期値が必要

今回の場合親からNavigation Linkを使って呼び出してるので、destinationに登録したSecondView()の中でtextに文字列を渡している。

NavigationLink(
  destination: SecondView(delegate: self, text: "Sucess send message"),
  label: {
    Text("Go to SecondView")
  })

delegateについては以下の子から親に渡す場合で説明するが、NavigationLinkのdestination毎に遷移先のViewとそのdelegateを呼び出せる。

子から親に値を渡す場合

このパターンはよく使うと思う。delegateパターンで実装している。

  1. 子である、SecondView.swiftにdelegateプロトコルを実装する。
protocol secondViewDelegate {
    func returnData(text: String)
}
struct SecondView: View {
    var delegate: secondViewDelegate?
  1. 親に渡すdelegateプロトコルのファンクションをButtonのaction: で呼び出す。
Button(action: {
  self.delegate?.returnData(text: "Success!!")
  self.presentation.wrappedValue.dismiss()
}, label: {
  Text("Try delegate")
})
  1. 親のContentView.swiftでSecondViewDelegateを追加。またNavigationLinkのdestinationでViewのdelegateをselfに設定する。このタイミングで設定できるのは便利。
struct ContentView: View, secondViewDelegate{
NavigationLink(
  destination: SecondView(delegate: self, text: "Sucess send message"),
  1. @State でProperty Wrapperでシステムに状態監視を移譲した変数を登録
@State var text: String = "not change yet"
  1. delegateファンクションでの処理を記述
func returnData(text: String) {
  self.text = text
}

NavigationLinkでbackボタンを使わずに戻る

@Environment はSwiftUIの環境変数で、これを使うことでいろいろと状態の監視や変更ができる。下記をSecondView.swiftに変数を作る。

@Environment(\.presentationMode) var presentation

これでpresentationModeの環境変数が取得できてるので、

Button(action: {
  self.delegate?.returnData(text: "Success!!")
  self.presentation.wrappedValue.dismiss()

と言う感じで、self.presentation.wrappedValue.dismiss()を呼び出せば画面を閉じることができる。これは他の画面遷移(例えばモーダルビューなど)でも同じ。

@Environmentについてはこちらの記事が詳しいです。
https://qiita.com/1amageek/items/59c6bb32a6627b4fb712

といった感じ。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?