SwiftUI: пользовательский модификатор .sheet необходимо прикрепить к верхнему окну приложения вместо просмотра.
Я осознаю важность порядка модификаторов в SwiftUI.
SwiftUI предоставляет два специальных модификатора:.alert(...)
&.sheet(...)
. Если эти модификаторы прикреплены из любой нижней иерархии представлений, то результат будет охватывать все представление.
Мне нужно создать собственный модификатор листа.(ex: .mobileSheetPresenter($isSheetPresented:...)
, который должен охватывать весь экран, даже если он применяется в любом месте иерархии нижнего просмотра.
The ViewModifier
нужно прикрепить кRoot Window
вместоView
как проблема, показанная в коде ниже.
struct MenuView: View {
@State private var isSheetPresented = false
var body: some View {
VStack {
VStack { // Yellow View
Button("Show Mobile Sheet") {
isSheetPresented.toggle()
}
.mobileSheetPresenter($isSheetPresented) {
Text("Hello, MobileSheet! with some long text")
}
}
.frame(width: 300, height: 200)
.background(.yellow)
VStack { // Red view
Text("Some Text")
}
.frame(width: 300, height: 200)
.background(.red)
}
}
}
Как вы можете видеть в приведенном выше коде, модификатор.mobileSheetPresenter($isSheetPresented)
прикреплен кButton
который заключен в рамку 300х300 желтого цвета.
Чуть нижеVStack
существует другой вид, привязанный к рамке 300X200.
Когда кнопка запускает презентацию листа, сам лист просто прикрепляется кYellow
просмотр в рамке 300х300.
Вот дальнейшие детали реализации
extension View{
func mobileSheetPresenter<InnerContent : View> (
_ isSheetPresented: Binding<Bool>,
@ViewBuilder _ innerContent: @escaping () -> InnerContent
) -> some View {
modifier(MobileSheetPresenter(isPresented: isSheetPresented,
on: innerContent))
}
}
public struct MobileSheetPresenter<InnerContent: View>: ViewModifier {
public var isPresented: Binding<Bool>
public var innerContent: () -> InnerContent
init( isPresented: Binding<Bool>,
@ViewBuilder on innerContent: @escaping () -> InnerContent
) {
self.isPresented = isPresented
self.innerContent = innerContent
}
public func body (content: Content) -> some View {
content
.overlay {
MobileSheet (
isPresented: isPresented
) {
innerContent()
}
}
}
}
Заранее спасибо, пожалуйста, дайте мне знать, если потребуется дополнительная информация.