NavigationLink で画面遷移すると自動的に次の画面の左上に<戻るボタンが付加されます。
しかし、世の様々なアプリではボタンの形状や色をアプリデザインに合わせてカスタマイズしている例をよく見ます。
今回はその戻るボタンのカスタマイズ方法について紹介していこうと思います。
※尚、SwiftUI 3.0 を前提とした内容となります。
【SwiftUI】戻るボタンをカスタマイズする方法
toolbar と ToolbarItem
SwiftUI 2.0 までは navigationBarItems というプロパティがありましたが 3.0 で deprecated(非推奨) となりました。
代わりに、toolbar プロパティとその中身となる ToolbarItem を使ってOSの戻るボタンの場所にカスタムしたボタンを配置します。
ToolbarItem(placement: ToolbarItemPlacement)
ToolbarItem の placement 引数に navigationBarLeading を指定することで画面左上にボタンを配置できます。
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
Button(...)
}
}
ちなみに navigationBarTrailing と bottomBar というものもありますが今回は触れません。
サンプルコード
遷移元
struct FirstView: View {
var body: some View {
NavigationView {
VStack {
NavigationLink("Go Next", destination: SecondView())
}
.navigationTitle("First View")
}
}
}
遷移先(戻るボタンを配置)
struct SecondView: View {
@Environment(\.dismiss) var dismiss
var body: some View {
VStack {
Text("Second View")
.padding()
}
.navigationTitle("Second View")
.navigationBarBackButtonHidden(true)
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
Button(
action: {
dismiss()
}, label: {
Image(systemName: "arrow.backward")
}
).tint(.orange)
}
}
}
}
ToolbarItem の中身である Button の action で環境変数の dismiss() をコールすることで前の画面へ戻れます。
また、navigationBarBackButtonHidden(true) でOSの戻るボタンを非表示にすることを忘れないようにしましょう。
ViewModifier化する
戻るボタンを表示したい画面全てで同じコードは書きたくないので、ViewModifier を継承してどこでも使えるようにしてみましょう。
CustomBackButton
ViewModifier を継承した CustomBackButton を作り処理を内包します。
struct CustomBackButton: ViewModifier {
@Environment(\.dismiss) var dismiss
func body(content: Content) -> some View {
content
.navigationBarBackButtonHidden(true)
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
Button(
action: {
dismiss()
}, label: {
Image(systemName: "arrow.backward")
}
).tint(.orange)
}
}
}
}
View の extension に追加
そして、View の extension の定義に customBackButton というプロパティを追加してシンプルに使えるようにします。
extension View {
func customBackButton() -> some View {
self.modifier(CustomBackButton())
}
}
使用例
struct SecondView: View {
var body: some View {
VStack {
Text("Second View")
.padding()
}
.navigationTitle("Second View")
.customBackButton()
}
}
先程よりだいぶスッキリしましたね。
以上、参考になりましたら嬉しいです。
macOS Big Sur 11.6
Xcode 13.1
iOS 15.0
iPhone 13 mini シミュレータ