タブバーに合わせて変化するナビゲーションバー
どうでしょう。下のTabBarに合わせて上のNavigationBarも切り替わっています!
良い感じですよね〜。とても良い感じにできています。
通常、ナビゲーションバーはNavigationView
を使って作っていきますが、私はNavigationViewには画像とテキストを一緒におく方法はないと思い込み、HStack
などを駆使して「なんちゃってナビゲーションバー」を作成しました。
以下がコードです。(ネタバレですがこれは失敗例です。)
仕組みとしては、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)
}
}
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()
}
}
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
が使われており、NavigationLink
はNavigationView
が必要らしいのです。なのでこのままでは、無理やり画面遷移させようとNavigationLink
とNavigationView
を追加すると以下のようになります。
まず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()
}
}
画面遷移はできますが、遷移先のタイトルバーが、作成したタイトルバーと雰囲気が違うのでレイアウトの統一感がなくなってしまいます。
これは...ダメだ...
ちゅら......。
#解決策
こう書きましょう。
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細胞はあります。
つらたんたん!!!!!!!!!!!
はい!!!終わり!!!!!!!!!!!!!!!