SwiftUI - PresentationButton with modal that is full screen

后端 未结 6 2092
滥情空心
滥情空心 2020-12-08 10:18

I am trying to implement a button that presents another scene with a \"Slide from Botton\" animation.

PresentationButton looked like a good candidate, so I gave it

6条回答
  •  暗喜
    暗喜 (楼主)
    2020-12-08 10:58

    So I was struggling with that and I didn't like the overlay feature nor the ViewController wrapped version since it gave me some memory bug and I am very new to iOS and only know SwiftUI and no UIKit.

    I developed credits the following with just SwiftUI which is probably what an overlay does but for my purposes it is much more flexible:

    struct FullscreenModalView: View where Presenting: View, Content: View {
    
        @Binding var isShowing: Bool
        let parent: () -> Presenting
        let content: () -> Content
    
        @inlinable public init(isShowing: Binding, parent: @escaping () -> Presenting, @ViewBuilder content: @escaping () -> Content) {
            self._isShowing = isShowing
            self.parent = parent
            self.content = content
        }
    
        var body: some View {
            GeometryReader { geometry in
                ZStack {
                    self.parent().zIndex(0)
                    if self.$isShowing.wrappedValue {
                        self.content()
                        .background(Color.primary.colorInvert())
                        .edgesIgnoringSafeArea(.all)
                        .frame(width: geometry.size.width, height: geometry.size.height)
                        .transition(.move(edge: .bottom))
                        .zIndex(1)
    
                    }
                }
            }
        }
    }
    

    Adding an extension to View:

    extension View {
    
        func modal(isShowing: Binding, @ViewBuilder content: @escaping () -> Content) -> some View where Content: View {
            FullscreenModalView(isShowing: isShowing, parent: { self }, content: content)
        }
    
    }
    

    Usage: Use a custom view and pass the showModal variable as a Binding to dismiss the modal from the view itself.

    struct ContentView : View {
        @State private var showModal: Bool = false
        var body: some View {
            ZStack {
                Button(action: {
                    withAnimation {
                        self.showModal.toggle()
                    }
                }, label: {
                    HStack{
                       Image(systemName: "eye.fill")
                        Text("Calibrate")
                    }
                   .frame(width: 220, height: 120)
                })
            }
            .modal(isShowing: self.$showModal, content: {
                Text("Hallo")
            })
        }
    }
    

    I hope this helps!

    Greetings krjw

提交回复
热议问题