IT アプリ開発

【SwiftUI】さまざまなSwiftUIの画面遷移について

2021年3月15日


画面遷移の方法はやり方次第で何通りもあると思いますが、
以下4つについて記載していこうと思います!

SwiftUIでは、isSheet(isPresented:True){}を記載することで、下から表示されるような画面遷移を実装することができます。

import SwiftUI

struct SecondView:View{
    
    @State private var show: Bool = false

    var body: some View {
        Text("teeeete")
        Button(action: { self.show.toggle() }) {
                Text("画面遷移Present").fontWeight(.bold).font(.largeTitle)
            }
            .sheet(isPresented: self.$show) {
                // trueになれば下からふわっと表示
                ThirdView()
            }
    }
}

struct ThirdView:View{
    var body: some View {
        Text("third")
    }
}

.sheet(isPresented: がtrueになるとSwiftでいうPresent遷移(下からふわっと表示される遷移)が実装できます。

struct LoginView: View {
    
    @State var user_id:String = ""
    @State var pass:String = ""
    @State var login_success:Bool = false
    
    @State var new_register:Bool = false
    

    var body: some View {
        VStack(){
            
            if(self.login_success){
                // ログイン完了した場合
                ContentView()
            } else if(self.new_register){
                NewRegister()
            } else {
                // 会員登録している場合
                Text("ログインをしてください").Title()
                Text("ユーザーid:").SubTitle()
                TextField("ユーザーidを入力してください",text: $user_id,
                    onEditingChanged: { isBegin in
                    if isBegin {
                        // 入力開始時に行いたい処理を実装する
                    } else {
                        // 入力終了時に行いたい処理を実装する
                        self.user_id = user_id
                    }
                },
                onCommit: {
                  //self.name = self.inputText
                  
                })
                 .textFieldStyle(RoundedBorderTextFieldStyle())
                 .padding()
                
                Text("パスワード:").SubTitle()
                SecureField("パスワードを入力してください",text: $pass,
                  onCommit: {
                    //self.name = self.inputText
                    
                  })
                   .textFieldStyle(RoundedBorderTextFieldStyle())
                   .padding()
                
                /* ログインする場合 */
                Button(
                    action: {
                      
                    },
                    label: {
                        Text("ログインする")
                    }
                ).background(Color.red)
                
                /* 新規会員登録する場合 */
                Button(
                    action: {
                        self.new_register.toggle()
                    },
                    label: {
                        Text("新規会員登録はこちら")
                    }
                ).background(Color.green)
  
            }
        }
    }
}

上記の例としてはログインIDとパスワードを入力して新規会員登録ボタンをクリックした時画面遷移する例ですが、
buttonをクリックした際、@Stateのnew_registerのフラグをtrueにして、Viewの再構築を行い、
新規会員登録画面を表示する形で画面遷移を行っています。

@Stateを使うことで、簡単に切り替えを行うことができ、
当然引数に値を渡すことで遷移先(子view)でも値を使うことができるようになります。

 

SwiftではNavigationControllerをstoryboard上に指定するか、そしてViewControllerクラス内にNavigationControllerクラスを生み出してコードで設定するなどを行っていました。

SwiftUIでは以下のようにNavigationViewを指定することで簡単に実装ができ、

NavigationLinkをViewに指定することでそこをタップしたときに次の遷移先のViewを指定でき、そのViewもNavigationの管理下になります。

Navigationを実装したいルートViewにNavigationViewを記載することにより、そのViewがルートViewとなります。

import SwiftUI

struct FirstView: View {
    
    var body: some View {
        VStack(){
            // NavigationViewを適用する
            NavigationView {
                List{
                    Section(header: Text("リスト")) {
                        ForEach(0..<5) { index in
                            Image("test_image")
                                .resizable()
                                .frame(width: 120, height: 90, alignment: .leading)
                                .clipShape(Circle())
                      
                            // リストのcellをタップしたとき遷移する。(矢印が表示される)
                            NavigationLink(destination: NextView()){}
                        }
                    }
                }
                .navigationBarTitle("1st View")  // NavigationBarに表示するテキストを指定
                .navigationBarHidden(false)      // NavigationBarを表示する
            }
        }
    }
}

 

上記ではListの各項目をタップした際に遷移するようなプログラムですが、ただボタンのようなものを配置した上で、
ナビゲーションで遷移したい場合は以下のように書くことができます。

NavigationLink(destination: () -> _, label: () -> _)

ButtonViewチックのように直感的にかけるのがいいですね。
NavigationLinkメソッドの引数では、
destinationに遷移先の表示させたいViewを、
labelにリンクでの表示名を指定します。

 

Button()のactionとlabelに近しい指定となるので、イメージはつきやすいかなと思います。

struct testView: View {
    
    var body: some View{
        NavigationView(){
            NavigationLink(destination: {
                testView2()               // 遷移先のView
            }, label: {
                Text("ページ1")
            })
        }
    }
    
}


struct testView2:View{
    
    var body: some View{
        VStack(){
            Text("ページ2")
        }
        .navigationTitle("ページ2")
    }
    
}

 

GeometryReaderを用いることで様々なViewの表示方法を独自で構築することが可能です。
例えば、メニューボタンをタップしたら右側から表示されるような画面遷移を実装するには、ZStackを利用します。
ZStackはViewをz軸上(前後)に配置するものです。
なので、通常の画面の上に右からメニューバーを表示したい場合は、
通常の画面を後ろに配置し、メニューバー用のviewを画面外に配置しておき、
メニューボタンがタップされたら、その画面外にあるメニューバー用のviewを画面内に移動させれば、
通常の画面上に右からばーが出てくるような画面遷移の実装が可能となります。

図で示すと以下のようなイメージです。

以下でサンプルコードを扱っています。
DragGestureで画面遷移

-IT, アプリ開発
-, ,

© 2024 Yosshi Labo. Powered by AFFINGER5