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
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