【Swift】画面を全て閉じて、ホーム画面に戻る

どうも、ねこきち(@nekokichi1_yos2)です。

 

今開いている画面を全て閉じて、ホーム画面(もしくは初期画面)へ1発で戻りたい場合があります。

 

かといって、

  • dismissを多用する → 処理の流れが複雑に
  • ホーム画面に遷移する → 画面が生成され、処理が圧迫される

の問題点が。

 

そこで、生成された画面を全て閉じて、最初の画面(ホーム画面)に戻る方法を書いていきます。

 

解説

 

方法は

  • RootViewController
  • presentingViewController
  • unWindSegue

を使った3つです。

 

RootViewController

 

RootViewControllerはアプリ画面の初期画面(アプリ起動時、最初に表示されるViewController ) 。

 

RootViewControllerでdismissを発動させると、RootViewController以降に開かれた画面(生成されたViewController)を全て削除する。

self.view.window?.rootViewController?.dismiss(animated: true, completion: nil)

 

結果、1番最初の画面に戻れる。

 

ドキュメントによると、

If you present several view controllers in succession, thus building a stack of presented view controllers, calling this method on a view controller lower in the stack dismisses its immediate child view controller and all view controllers above that child on the stack.

 

複数のビューコントローラーを連続して提示し、提示されたビューコントローラーのスタックを構築する場合、スタックの下位にあるビューコントローラーでこのメソッドを呼び出すと、その直接の子ビューコントローラーと、スタック上のその子より上のすべてのビューコントローラーが閉じます。

 

引用:Appleドキュメントより 

https://developer.apple.com/documentation/uikit/uiviewcontroller/1621505-dismiss

なので、親であるRootViewControllerより上の、子であるViewController達を削除するってことかな?

 

presentingViewController

 

開いている画面を指定して、直接閉じる方法。

self.presentingViewController?.dismiss(animated: true, completion: nil)

 

注意点として、rootViewController(アプリ起動時の画面)から1つの画面が開かれている場合、

self.presentingViewController?.presentingViewController?.dismiss(animated: true, completion: nil)

と指定しないと、RootViewControllerには戻れない。

 

もし1つだけだと、現在表示している画面しか閉じない。

 

f:id:nekokichi_yos2:20200729232048j:plain

 

なので、

  • 現在の画面とRootViewControllerの間にある画面の数 + 1

を指定した方がいい。

 

unWindSegue 

 

Segueを利用した方法。

@IBAction func unwindSegue(for unwindSegue: UIStoryboardSegue, towards subsequentVC: UIViewController) {}

 

手順は、

  1. 1番最初の画面(ホーム画面)に上記のメソッドを記述
  2. StoryBoardで処理を実行したいUI(例:UIButton)をcontrolキーを押下しながらExitと紐づける
  3. 1番最初の画面で定義したメソッドを選択

 

(★ここ重要)unWindSegueは、unWindSegueのメソッドを定義した画面に戻るので、もしホーム画面に戻るなら、ホーム画面に記述する。

 

(2:UIとExitの紐付け)

f:id:nekokichi_yos2:20200729233205p:plain

 

(3:戻り先で定義したunWindSegueのメソッドを選択)

f:id:nekokichi_yos2:20200729233202p:plain

 

結果

 

StoryBoard

f:id:nekokichi_yos2:20200729223120p:plain

(CloseAll - 4つ目の画面 - ButtonはExitでunWindSegueのメソッドと紐付け)

 

dismissの場合 

f:id:nekokichi_yos2:20200729223144g:plain

  

unwindSegueの場合

f:id:nekokichi_yos2:20200729223159g:plain

  

ソースコード

 

rootViewController(最初の画面)

import UIKit

class rootViewController: UIViewController {
    
    @IBAction func unwindSegue(for unwindSegue: UIStoryboardSegue, towards subsequentVC: UIViewController) {
    }

}

 

closeAll(4つ目の画面)

import UIKit

class CloseAll: UIViewController {
    
    @IBAction func closeAllViewController(_ sender: Any) {
        self.view.window?.rootViewController?.dismiss(animated: true, completion: nil)
        self.presentingViewController?.presentingViewController?.presentingViewController?.dismiss(animated: true, completion: nil)
    }
    
}

 

参考

 

stackoverflow.com

stackoverflow.com

stackoverflow.com

www.ikkitang1211.site