首页 > 解决方案 > Dismiss modal automatically after 1 sec of being shown - swiftui

问题描述

is there a way to dismiss a modal(.sheet) automatically after 1 sec of being shown? without any user intervention.

I want to show it coming from the bottom, 1 sec, then gone (if possible with animation going up)

Basically I have 1 view showing a match information, then I click next or dislike and I want to show a fullScreenCover for 1 sec, to hide my ugly scroll to the top to show the next match. it's the same view but showing a new element in an array

thanks / merci / gracias

                    ScrollViewReader {ProxyReader in
                        ScrollView(.vertical, showsIndicators: false, content: {
                            
                            Group {
                                //CustomImageView(urlString: model.matches[index].imageUrl3 ?? "")
                                if model.matches[index].imageUrl3 == "" {
                                    Image(systemName: "person")
                                        .frame(width: 300, height: 300, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/)
                                        .aspectRatio(contentMode: .fit)
                                } else {
                                    
                                    RemoteImage(url: model.matches[index].imageUrl3!)
                                        .aspectRatio(contentMode: .fit)
                                        .frame(width: 200)
                                }
                                Text(model.matches[index].bucketList)
                            }.padding()
                            
                        })//scroll view
                        //to recreate the veiw from scratch
                        .id(self.scrollViewID)
                        //this is to show the rejection button
                        .overlay(
                            Button(action: {
                                //move to the next match
                                self.isPresented.toggle()
                                
                                if self.index == model.matches.count-1 {
                                    //go back to first match
                                    self.index = 0
                                } else {
                                    self.index += 1
                                }
                                
                                //scroll to top
                                withAnimation(.spring()) {
                                    ProxyReader.scrollTo("SCROLL_TO_TOP", anchor: .top)
                                    
                                    //how to dismiss and delay animation for 2 secs!!
                                    self.isPresented.toggle()
                                }
                                
                                
                            }, label: {
                                Image(systemName: "xmark.circle.fill")
                                    .font(.system(size:50, weight: .semibold))
                                    .foregroundColor(.white)
                                    .padding()
                                    .background(Color("red"))
                                    .clipShape(Circle())
                            })
                            .padding(.trailing)
                            .padding(.bottom, getSafeArea().bottom == 0 ? 12 : 0) //this is an if statement
                            //.opacity(-scrollViewOffset > 450 ? 1 : 0)
                            .animation(.easeInOut)
                            
                            //to show rejection transition
                            .fullScreenCover(isPresented: $isPresented, content: {
                                FullScreenModalView.init(
                                    DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
                                        isPresented = false
                                    }
                                )
                                
                            })

标签: swiftswiftui

解决方案


If I get what you are asking, a solution is to use DispatchQueue.main.asyncAfter():

//to show rejection transition
.fullScreenCover(isPresented: $isPresented, content: {
     FullScreenModalView.init()
        DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
              isPresented = false
        }

})

Please note that this may not be exactly precise as the firing time depends upon how busy the OS is at that moment, but it will generally be very good. Also, you generally want some user interaction in dismissing a modal as the user may look away in the second you display it.


推荐阅读