Issue #823
Make atomic components and compose them. Firstly with NavigationBar
that has custom leading and trailing content, there we can customize padding.
import SwiftUI
struct NavigationBar<Leading: View, Trailing: View>: View {
@ViewBuilder let leading: Leading
@ViewBuilder let trailing: Trailing
var body: some View {
HStack {
leading
Spacer()
trailing
}
.padding(.horizontal, 8)
}
}
struct NavigationBarWithBackButton: View {
let onBack: () -> Void
var body: some View {
NavigationBar(
leading: backButton,
trailing: EmptyView.init
)
}
private func backButton() -> some View {
Button(action: onBack) {
Image(systemName: "arrow.back")
.resizable()
.renderingMode(.template)
.foregroundColor(Color.gray)
.frame(width: 18, height: 18)
}
}
}
Then we can make a container for our custom content, using VStack
with our custom navigation bar on top
import SwiftUI
struct NavigationContent<NavigationBar: View, Content: View>: View {
@ViewBuilder let navigationBar: NavigationBar
@ViewBuilder let content: Content
var body: some View {
VStack(alignment: .leading, spacing: 0) {
navigationBar
content
}
.navigationBarHidden(true)
.navigationBarBackButtonHidden(true)
}
}
Below is a sample SettingsView that use our custom navigation
NavigationView {
SettingsView()
}
struct SettingsView: View {
@Environment(\.presentationMode) private var presentationMode: Binding<PresentationMode>
var body: some View {
NavigationContent(
navigationBar: navigationBar,
content: content
)
}
private func navigationBar() -> some View {
NavigationBarWithBackButton(onBack: {
presentationMode.wrappedValue.dismiss()
})
}
private func content() -> some View {
Text("Settings View")
}
}