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()
                }
            }
    }
}

Заранее спасибо, пожалуйста, дайте мне знать, если потребуется дополнительная информация.

0 ответов

Другие вопросы по тегам