4
3

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.

【SwiftUI】失敗作を無駄死にさせないシリーズ:NavigationBarもどき

Last updated at Posted at 2021-03-18

タブバーに合わせて変化するナビゲーションバー

を作成しました。
ファイル名

どうでしょう。下のTabBarに合わせて上のNavigationBarも切り替わっています!
良い感じですよね〜。とても良い感じにできています。

通常、ナビゲーションバーはNavigationViewを使って作っていきますが、私はNavigationViewには画像とテキストを一緒におく方法はないと思い込み、HStackなどを駆使して「なんちゃってナビゲーションバー」を作成しました。

以下がコードです。(ネタバレですがこれは失敗例です。)
仕組みとしては、NavigationBarViewファイルに、画像とテキストをまだ設定してないナビゲーションバーを作ります。そしてナビゲーションバーを表示したいファイルでNavigationBarViewを呼び出し、引数に適切な画像とテキストを入れることで、それぞれの画面ごとにナビゲーションバーに表示される画像とテキストを変えているのです。あ、全然天才とかじゃないですっ///💦

NavigationBarView
import SwiftUI

struct NavigationBarView: View {
    let image: Image
    let titleName: String
    
    var body: some View {
        
        HStack {
            VStack(alignment: .leading) {
                image
                    .resizable()
                    .frame(width: 30, height: 30)
                    .foregroundColor(.white)
                    .padding(10)
            }
            ZStack {
                Text("\(titleName)")
                    .fontWeight(.medium)
                    .foregroundColor(.white)
                    .font(.title)
            }
            Spacer()
        }
        .background(Color.orange)
    }
}
ProfileListView
import SwiftUI

struct ProfileListView: View {
    
    var width = UiComponent.screenWidth
    var height = UiComponent.screenHeight - 50
    
    
    var body: some View {
        ZStack {
            VStack {
                ForEach(0 ..< 4) {_ in
                    ProfileRow()
                }
            }
            VStack {
                VStack {
                    NavigationBarView(
                        image: Image(systemName: "list.bullet"),
                        titleName: "プロフィール一覧"
                    )
                    .frame(width: width, height: 50)
                }
                Spacer()
            }
        }
    }
}

struct ProfileListView_Previews: PreviewProvider {
    static var previews: some View {
        ProfileListView()
    }
}
ProfileRegisterView
import SwiftUI

struct ProfileRegisterView: View {
    var width = UiComponent.screenWidth
    
    var body: some View {
        ZStack {
            HStack {
                Text(/*@START_MENU_TOKEN@*/"Placeholder"/*@END_MENU_TOKEN@*/)
            }
            VStack {
                VStack {
                    NavigationBarView(
                        image: Image(systemName: "person.circle.fill"), titleName: "プロフィール登録"
                    )
                    Spacer()
                }
            }
        }
    }
}

struct TabRegister_Previews: PreviewProvider {
    static var previews: some View {
        ProfileRegisterView()
    }
}

しかし、問題があるのです。

実は、仕様として、コアラ太郎のカードをタップすると画面遷移するようにしたいのですが、swiftUIの画面遷移にはNavigationLinkが使われており、NavigationLinkNavigationViewが必要らしいのです。なのでこのままでは、無理やり画面遷移させようとNavigationLinkNavigationViewを追加すると以下のようになります。

まずProfileListViewファイルを以下のように変更します

ProfileListView
import SwiftUI

struct ProfileListView: View {
    
    var width = UiComponent.screenWidth
    var height = UiComponent.screenHeight - 50
    
    
    var body: some View {
        NavigationView{
            ZStack {
                VStack {
                    ForEach(0 ..< 4) {_ in
                        NavigationLink(destination: EmptyView()){
                        ProfileRow()
                        }
                    }
                }
                VStack {
                    VStack {
                        NavigationBarView(
                            image: Image(systemName: "list.bullet"),
                            titleName: "プロフィール一覧"
                        )
                        .frame(width: width, height: 50)
                    }
                    Spacer()
                }
            }
        }
    }
}

struct ProfileListView_Previews: PreviewProvider {
    static var previews: some View {
        ProfileListView()
    }
}

するとレイアウトが崩れます。
ファイル名

画面遷移はできますが、遷移先のタイトルバーが、作成したタイトルバーと雰囲気が違うのでレイアウトの統一感がなくなってしまいます。

ファイル名

これは...ダメだ...

ちゅら......。

#解決策
こう書きましょう。

ProfileListView

import SwiftUI

struct ProfileListView: View {
    
    var width = UiComponent.screenWidth
    var numbers = [1, 2, 3, 4, 5]
    
    init() {
        UINavigationBar.appearance().backgroundColor = UIColor.orange
    }
    
    var body: some View {
        // ナビゲーションビュータグで囲む(ナビゲーション遷移するため)
        NavigationView {
            VStack {
                ForEach(0 ..< 5) {_ in
                    // ナビゲーション遷移
                    NavigationLink(destination: EmptyView()){
                        ProfileRow()
                    }
                }
            }
            // ナビゲーションバータイトルをつける
            .navigationBarTitleDisplayMode(.inline)
            // カスタムナビゲーションを作る(中でHSTackのView)
            .toolbar {
                ToolbarItem(placement: .principal) {
                    HStack {
                        Image(systemName: "person.circle.fill")
                        Text("プロフィール登録").font(.headline)
                    }.foregroundColor(.orange)
                }
            }
        }
    }
}



struct ProfileListView_Previews: PreviewProvider {
    static var previews: some View {
        ProfileListView()
    }
}

もうこれだけで行けるのです...
NavigationBarViewとかいらんのです...

こんな感じになります。
ファイル名
画面遷移もちゃんとできます。
キャプチャとるの忘れましたができます。STAP細胞はあります。

つらたんたん!!!!!!!!!!!
はい!!!終わり!!!!!!!!!!!!!!!

4
3
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
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?