我尝试重新创建.toolbar
Apple 为其NavigationView
. 我创建了一个自己的实现,NavigationStackView
但也想使用.toolbar
修饰符。
我可以使用环境对象和自定义视图修改器来工作,但是当我不应用.toolbar
修改器时,这将不起作用,因为没有设置环境对象。
有一个更好的方法吗?苹果是如何做到这一点的?
例子:
import Foundation
import SwiftUI
class ToolbarData: ObservableObject {
@Published var view: (() -> AnyView)? = nil
init(_ view: @escaping () -> AnyView) {
self.view = view
}
}
struct NavigationStackView<Content: View>: View {
@ViewBuilder var content: () -> Content
@EnvironmentObject var toolbar: ToolbarData
var body: some View {
VStack(spacing: 0) {
HStack(spacing: 0) {
if (toolbar.view != nil) {
toolbar.view!()
}
}
Spacer()
content()
Spacer()
}
}
}
struct NavigationStackToolbar<ToolbarContent: View>: ViewModifier {
var toolbar: ToolbarContent
func body(content: Content) -> some View {
content
.environmentObject(ToolbarData({
AnyView(toolbar)
}))
}
}
extension NavigationStackView {
func toolbar<Content: View>(_ content: () -> Content) -> some View {
modifier(NavigationStackToolbar(toolbar: content()))
}
}
struct NavigationStackView_Previews: PreviewProvider {
static var previews: some View {
NavigationStackView {
Text("Test")
}
.toolbar {
Text("Toolbar")
}
}
}
当前解决方案:
import Foundation
import SwiftUI
private struct ToolbarEnvironmentKey: EnvironmentKey {
static let defaultValue: AnyView = AnyView(EmptyView())
}
extension EnvironmentValues {
var toolbar: AnyView {
get { self[ToolbarEnvironmentKey.self] }
set { self[ToolbarEnvironmentKey.self] = newValue }
}
}
struct NavigationStackView<Content: View>: View {
@ViewBuilder var content: () -> Content
@Environment(\.toolbar) var toolbar: AnyView
var body: some View {
VStack(spacing: 0) {
HStack(spacing: 0) {
toolbar
}
Spacer()
content()
Spacer()
}
}
}
extension NavigationStackView {
func toolbar<Content: View>(_ content: () -> Content) -> some View {
self
.environment(\.toolbar, AnyView(content()))
}
}
struct NavigationStackView_Previews: PreviewProvider {
static var previews: some View {
NavigationStackView {
Text("Test")
}
.toolbar {
Text("Toolbar")
}
}
}