I'm trying to create popup in SwiftUI and faced some problems. Some of them like a different .transition
on the same View
solved by tips from SO, but some still hard to resolve.
There are few problems in code example:
- Popup view animate incorrect when you first time call it. It's just appear but not coming from the bottom
- It seems like two types of
.transition
applying to popup, but it should be one to each part of it - Data on the back View start to glitching when popup appears and disappears
- And finally popup doesn't come from the bottom and disappears before coming to the edge
Code example
struct SOAnimation: View {
@State var selectedImage = "camera.filters"
@State var showPopup = false
@State var showView = true
var body: some View {
ZStack(alignment: .top) {
VStack {
Text("Image").font(.largeTitle).fontWeight(.bold)
ZStack {
Image(systemName: "circle.fill")
.resizable()
.frame(width: 81, height: 81)
.foregroundColor(Color.blue.opacity(0.2))
Image(systemName: selectedImage)
.resizable()
.frame(width: 44, height: 44)
} .onTapGesture {
withAnimation(.spring()) {
showPopup = true
}
}
VStack(alignment: .leading) {
ForEach(1..<25) { _ in
Text(UUID().uuidString)
.fontWeight(.semibold)
}
}
Spacer()
}
if showPopup { Popup(selectedImage: $selectedImage, showPopup: $showPopup)}
}
}
}
struct Popup: View {
@Binding var selectedImage: String
@Binding var showPopup: Bool
private let columns: [GridItem] = Array(repeating: .init(.flexible()), count: 4)
private let images = ["camera.filters", "seal", "circle", "oval", "app", "diamond", "octagon", "play", "pause", "forward", "goforward", "wave.3.forward", "skew"]
var body: some View {
ZStack {
if showPopup { // Logic for different types of transition
Color.black.opacity(0.5)
.onTapGesture { withAnimation(.spring()) { showPopup = false }}
.ignoresSafeArea(edges: .all)
.transition(.opacity)
}
if showPopup { // Logic for different types of transition
LazyVGrid(columns: columns, alignment: .center, spacing: 20) {
ForEach(images, id: \.self) { image in
Image(systemName: image)
.resizable()
.frame(width: 30, height: 30)
.onTapGesture {
selectedImage = image
withAnimation(.spring()) { showPopup = false }
}
}
}
.padding()
.onTapGesture {}
.background(Color.white)
.cornerRadius(20)
.transition(.move(edge: .bottom))
.padding(.horizontal)
}
}
}
}
Code example result:
Expected result: