Q&A
実現したいこと
Swift UIのTabViewでページごとにSearchBarの表示/非表示を切り替えたい
前提
現在Swift UIでTabViewの実装を進めております。
TabPage1-3の3つのビューを切り替えることができるようにしようとしております。
その中で、TabPage1と2はモディファイア .searchable()でsearchBarを表示し、
TabPage3のみsearchBarを非表示にしようとしております。
発生している問題・エラーメッセージ
現在、extension(拡張)を使用することで、選択したタブによって、searchBarの表示/非表示をの切り替えが可能になりましたが、一度searchBarがないTabPage3を開いた後、TabPage1または2を開くと、NavigationBarが透明になり、正しく表示されなくなります。(以下の画像を参照)
該当のソースコード
Swift
1import SwiftUI 2 3struct TopView: View{ 4 @State var selection = 1 5 @State private var searchText: String = "" 6 @State var showDelete = false 7 var body: some View { 8 NavigationStack { 9 TabView(selection: $selection) { 10 RouteView(searchText: $searchText) 11 .tabItem{ 12 Label("Tab1", systemImage: "map.circle") 13 } 14 .tag(1) 15 PoleView(searchText: $searchText) 16 .tabItem{ 17 Label("Tab2", systemImage: "mappin.circle") 18 } 19 .tag(2) 20 FavoriteView() 21 .tabItem{ 22 Label("Tab3", systemImage: "heart") 23 } 24 .tag(3) 25 } 26 .navigationBarTitle(Text(self.selection == 1 || self.selection == 2 ? (self.selection == 1 ? "路線検索" : "停留所検索"): "お気に入り")) 27 .navigationBarTitleDisplayMode(.inline) 28 .if(self.selection == 1 || self.selection == 2){ view in 29 view.searchable(text: $searchText, placement: .navigationBarDrawer , prompt: self.selection == 2 ? "停留所名から検索" : "系統名から検索") 30 } 31 } 32 } 33} 34 35extension View { 36 @ViewBuilder func `if`<Content: View>(_ condition: Bool, transform: (Self) -> Content) 37 -> some View { 38 if condition { 39 transform(self) 40 } else { 41 self 42 } 43 } 44} 45 46struct RouteView: View{ 47 @Binding var searchText: String 48 var body: some View { 49 List{ 50 ForEach(0 ..< 20){ index in 51 Text("TabPage1") 52 } 53 } 54 } 55} 56 57struct PoleView: View{ 58 @Binding var searchText: String 59 var body: some View { 60 List{ 61 ForEach(0 ..< 20){ index in 62 Text("TabPage2") 63 } 64 } 65 } 66} 67 68struct FavoriteView: View{ 69 var body: some View { 70 List{ 71 ForEach(0 ..< 20){ index in 72 Text("TabPage3") 73 } 74 } 75 } 76} 77 78struct TopView_Previews: PreviewProvider { 79 static var previews: some View { 80 TopView() 81 } 82} 83
試したこと
TabView()自体をNavigationStackで囲うのではなく、下記のように、ViewをそれぞれNavigationStackで囲むと、NavigationBarは透明にならず、正しく表示されます。
しかしながら、この実装の場合、TabView()内のViewから、さらに新しいViewに遷移する場合に、ページ下部のタブバーが残ってしまいます。(コードが複雑になるため、新しいViewに遷移するためのコードは記載しておりません。)新しいViewに遷移する場合に、タブバーが残らないようにしたいので、この実装はできません。
もし、「該当のソースコード」の方法で、NavigationBarを正しく表示できる方法をご存知の方がいらっしゃいましたら、ご教示いただけますと幸いです。
よろしくお願いいたします。
Swift
1import SwiftUI 2 3struct TopView: View{ 4 @State var selection = 1 5 @State private var searchText: String = "" 6 @State var showDelete = false 7 var body: some View { 8 TabView(selection: $selection) { 9 NavigationStack { 10 RouteView(searchText: $searchText) 11 } 12 .tabItem{ 13 Label("Tab1", systemImage: "map.circle") 14 } 15 .tag(1) 16 NavigationStack { 17 PoleView(searchText: $searchText) 18 } 19 .tabItem{ 20 Label("Tab2", systemImage: "mappin.circle") 21 } 22 .tag(2) 23 NavigationStack { 24 FavoriteView() 25 } 26 .tabItem{ 27 Label("Tab3", systemImage: "heart") 28 } 29 .tag(3) 30 } 31 } 32} 33 34extension View { 35 @ViewBuilder func `if`<Content: View>(_ condition: Bool, transform: (Self) -> Content) 36 -> some View { 37 if condition { 38 transform(self) 39 } else { 40 self 41 } 42 } 43} 44 45struct RouteView: View{ 46 @Binding var searchText: String 47 var body: some View { 48 List{ 49 ForEach(0 ..< 20){ index in 50 Text("TabPage1") 51 } 52 } 53 .navigationBarTitle("路線検索") 54 .navigationBarTitleDisplayMode(.inline) 55 .searchable(text: $searchText, placement: .navigationBarDrawer) 56 } 57} 58 59struct PoleView: View{ 60 @Binding var searchText: String 61 var body: some View { 62 List{ 63 ForEach(0 ..< 20){ index in 64 Text("TabPage2") 65 } 66 } 67 .navigationBarTitle("停留所検索") 68 .navigationBarTitleDisplayMode(.inline) 69 .searchable(text: $searchText, placement: .navigationBarDrawer) 70 } 71} 72 73struct FavoriteView: View{ 74 var body: some View { 75 List{ 76 ForEach(0 ..< 20){ index in 77 Text("TabPage3") 78 } 79 } 80 .navigationBarTitle("お気に入り") 81 .navigationBarTitleDisplayMode(.inline) 82 } 83} 84 85struct TopView_Previews: PreviewProvider { 86 static var previews: some View { 87 TopView() 88 } 89}
補足情報(FW/ツールのバージョンなど)
あなたの回答
tips
プレビュー