Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Animation Glitch on FullScreen Implementation. #97

Closed
dentvii opened this issue May 19, 2024 · 4 comments
Closed

Animation Glitch on FullScreen Implementation. #97

dentvii opened this issue May 19, 2024 · 4 comments
Assignees
Labels

Comments

@dentvii
Copy link

dentvii commented May 19, 2024

First of all, thank you for the amazing package!

I'm encountering an issue when using popups in combination with views that contain .edgesIgnoringSafeArea(.all). Specifically, I've noticed that when the popup has contentIgnoresSafeArea set to either true or false, the following glitches occur:

  1. Animation Glitch:

    • When the popup animation goes from bottom to top, it stops at the safe area boundary before continuing. This results in a noticeable hitch in the animation.
  2. Post-Dismissal Lag:

    • After dismissing the popup, there is an animation lag where a thin component of the view remains visible momentarily.

I would greatly appreciate any assistance in resolving this issue.


struct WebViewWrapperView: View {
    
    @Environment(\.presentationMode) private var presentation

    let title : String
    let request: URLRequest
    
    var body: some View {
        VStack {
            navigationBar
            
            titleView
            
            WebView(request: request)
        }
    }
    private var titleView : some View {
        HStack{
            Text(title)
                .modifier(Manrope40Bold())
                .fixedSize(horizontal: false, vertical: true)
                .foregroundColor(Color.black)
                .padding(.bottom, 12)
            Spacer()
        }.padding(.horizontal)
    }
    
    private var navigationBar : some View {
        return HStack {
            Button(action: {
                self.presentation.wrappedValue.dismiss() // dismiss the navigation view
                PopupManager.dismiss()
            }, label: {
                RoundButtonStyleView(buttonType: .backArrow, widthAndHeight: 36, tintColor: .gray, iconColor: .black)

            })
            Spacer()
            
            
        }
        .padding(.horizontal)
        .padding(.top, 60)
    }
}

import SwiftUI
import MijickPopupView

struct PopupFullScreen<Content: View>: BottomPopup {
    var cornerRadius: CGFloat?
    var contentIgnoresSafeArea: Bool?
    var horizontalPadding: CGFloat?
    var backgroundColor: Color?
    var content: () -> Content
    
    init(
        cornerRadius: CGFloat? = nil,
        contentIgnoresSafeArea: Bool? = nil,
        horizontalPadding: CGFloat? = nil,
        backgroundColor: Color? = nil,
        @ViewBuilder content: @escaping () -> Content
    ) {
        self.content = content
        self.cornerRadius = cornerRadius
        self.contentIgnoresSafeArea = contentIgnoresSafeArea
        self.horizontalPadding = horizontalPadding
        self.backgroundColor = backgroundColor
    }
    
    func configurePopup(popup: BottomPopupConfig) -> BottomPopupConfig {
        var modifiedPopup = popup
            .contentFillsEntireScreen(true)
            .dragGestureEnabled(false)
        if let cornerRadius = cornerRadius {
            modifiedPopup = modifiedPopup.cornerRadius(cornerRadius)
        }
        if let contentIgnoresSafeArea = contentIgnoresSafeArea {
            modifiedPopup = modifiedPopup.contentIgnoresSafeArea(contentIgnoresSafeArea)
        }
        if let horizontalPadding = horizontalPadding {
            modifiedPopup = modifiedPopup.horizontalPadding(horizontalPadding)
        }
        if let backgroundColor = backgroundColor {
            modifiedPopup = modifiedPopup.backgroundColour(backgroundColor)
        }
        return modifiedPopup
    }
    
    func createContent() -> some View {
        content()
            .frame(maxHeight: .infinity, alignment: .top)
    }
}

 private func configurePopup(_ config: GlobalConfig) -> GlobalConfig { config
        .top { $0
            .cornerRadius(24)
            .dragGestureEnabled(true)
            .tapOutsideToDismiss(true)
        }
        .centre { $0
            .tapOutsideToDismiss(false)
        }
        .bottom { $0
            .stackLimit(4)
            .tapOutsideToDismiss(true)
        }
    }

Simulator Screen Recording - Traft - iPhone 14 PM 16 4 - 2024-05-18 at 23 07 18
Simulator Screen Recording - Traft - iPhone 14 PM 16 4 - 2024-05-18 at 23 09 55

@FulcrumOne
Copy link
Contributor

Hey @dentvii!

Thank you for these words and this amazing description, it will help us a lot in understanding the source of the problem!

Regarding the first point, I would advise delaying the loading of the content of the popup (0.5 seconds should be enough). Here you have an example how you can achieve it:

(...)
@State private var showContent: Bool = false
(...)

    func createContent() -> some View {
        (...)
        .animation(.easeInOut, value: showContent)
        .onAppear() {
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { showContent = true }
        }
    }
    
    (...)
    
    @ViewBuilder func createWebView() -> some View { if showContent {
        WebView()
    }}
    
    (...)

This problem occurs because both WKWebView and StoreKit are extremely CPU intensive (especially if there's nothing in cache memory yet).

Regarding the second problem, thank you for pointing it out, I thought it had already been fixed, I will fix it later this week (sorry for the delay, but we are busy preparing an update for Navigattie, our second library).

Once again, I would like to thank you for these discoveries and have a great day!

@dentvii
Copy link
Author

dentvii commented May 21, 2024

Thank you for your quick response and your interest in fixing this issue!

I believe the problem is related to the edgesIgnoreSafeArea property. Here’s how you can reproduce the views and observe the issue:


fileprivate struct MockSubscriptionAlternative01View: View {
    
    
    var body: some View {
        ZStack {
            ImageBackground()
            LinearGradientView()
            
            ScrollView(.vertical, showsIndicators: false) {
                VStack {
                    CloseButtonView()
                    Spacer()
                }.padding(.horizontal, 30)
            }
            
        }
        .edgesIgnoringSafeArea(.all)
    }
}

fileprivate struct LinearGradientView: View {
    var body: some View {
        LinearGradient(gradient: Gradient(colors: [Color.blue.opacity(0.4), Color.blue, Color.blue]), startPoint: .top, endPoint: .bottom)
    }
}

fileprivate struct ImageBackground: View {
    var body: some View {
        VStack {
            Image("subscription01")
                .resizable()
                .scaledToFit()
                .border(Color.red)
                .scaleEffect(1.4)
                .offset(x: 70, y: 0)
            Spacer()
        }
    }
}

fileprivate struct CloseButtonView: View {
    var body: some View {
        HStack {
            Button(action: {
                PopupManager.dismiss()
            }) {
                RoundButtonStyleView(buttonType: .close, widthAndHeight: 36, tintColor: Color.white.opacity(0.1), iconColor: Color.white.opacity(0.6))
                    .shadow(color: Color.black.opacity(0.5), radius: 4)
                    // .background(Color.black.clipShape(Circle()).opacity(0.3))
            }
            
            Spacer()
        }
        .padding(.top, 50)
    }
}



fileprivate struct PopupDemoView: View {
    var body: some View {
        VStack (spacing: 10) {
            Button("Top", action: {
                PopupTopNotification(horizontalPadding: 20) {
                    VStack {
                        Color.red
                    }
                }.showAndStack()
            })
            
            Button("Center", action: {
                PopupCenter (horizontalPadding: 20) {
                    VStack {
                        Text("Unlock New Features")
                            .foregroundColor(.black)
                            .multilineTextAlignment(.center)
                            .fixedSize(horizontal: false, vertical: true)
                        
                        Text("Proident adipisicing labore consectetur tempor eiusmod ullamco enim adipisicing eiusmod.")
                            .foregroundColor(.black)
                            .multilineTextAlignment(.center)
                            .fixedSize(horizontal: false, vertical: true)
                        
                        HStack {
                            Text("Cancel")
                                .foregroundColor(.black)
                                .frame(height: 46)
                                .frame(maxWidth: .infinity)
                                .cornerRadius(8)
                            
                            Text("Unlock")
                                .foregroundColor(.black)
                                .frame(height: 46)
                                .frame(maxWidth: .infinity)
                                .cornerRadius(8)
                        }
                    }
                }.showAndStack()
            })
            Button("Full screen Mock Subscription", action: {
                PopupFullScreen {
                    MockSubscriptionAlternative01View()
                        .onTapGesture {
                            PopupManager.dismiss()
                        }
                }.showAndStack()
            })
            Button("Full screen", action: {
                PopupFullScreen {
                    Color.green                        .onTapGesture {
                            PopupManager.dismiss()
                        }
                }.showAndStack()
            })
            Button("Sheet", action: {
                PopupSheet (backgroundColor: Color.white){
                    VStack {
                        
                        Capsule()
                            .fill(Color.gray)
                            .frame(width: 32, height: 6)
                            .padding(.vertical)
                        
                        Color.green
                    }
                        .onTapGesture {
                            PopupManager.dismiss()
                        }
                }.showAndStack()
            })
            Button("Sheet", action: {
                PopupSheet (contentFillsWholeHeigh: false){
                    VStack {
                        Text("Unlock New Features")
                            .foregroundColor(.black)
                            .multilineTextAlignment(.center)
                            .fixedSize(horizontal: false, vertical: true)
                        
                        Text("Proident adipisicing labore consectetur tempor eiusmod ullamco enim adipisicing eiusmod.")
                            .foregroundColor(.black)
                            .multilineTextAlignment(.center)
                            .fixedSize(horizontal: false, vertical: true)
                    }.padding()
                        .onTapGesture {
                            PopupManager.dismiss()
                        }
                }.showAndStack()
            })
            Button("Bottom Notification", action: {
                PopupBottomNotification {
                    Color.green.frame(50)
                        .onTapGesture {
                            PopupManager.dismiss()
                        }
                }.showAndStack()
            })
        }
        .background(Color.traftRedLight)
    }
}

fileprivate struct CustomPreviewProviderView : View {
    @State var theme: Theme  = .Light
    
    init(theme: Theme = .Light) {
        self.theme = theme
    }
    
    var body: some View {
        ZStack {
            Color.blue
            PopupDemoView()
        }
        .implementPopupView(config: configurePopup)
        .environmentObject(themeManager)
    }
    
    
    func configurePopup(_ config: GlobalConfig) -> GlobalConfig { config
        .top { $0
            .cornerRadius(24)
            .dragGestureEnabled(true)
            .tapOutsideToDismiss(true)
        }
        .centre { $0
            .tapOutsideToDismiss(true)
        }
        .bottom { $0
            .stackLimit(4)
            .dragGestureEnabled(true)
            .tapOutsideToDismiss(true)
        }
    }
    
}


struct PopupDemoView_Previews: PreviewProvider {
    static var previews: some View {
        CustomPreviewProviderView()
    }
}

FullScreenEdgesBug

@FulcrumOne
Copy link
Contributor

Thanks @dentvii

@FulcrumOne
Copy link
Contributor

@dentvii, the problem should be resolved with patch-2.4.2 branch. To make it work, please delete ignoresSafeArea from your MockSubscriptionAlternative01View structure and declare your popup as:

PopupFullScreen(contentIgnoresSafeArea: true) {
                    MockSubscriptionAlternative01View()
                        .onTapGesture {
                            PopupManager.dismiss()
                        }
                }.showAndStack()

Uploading CleanShot 2024-05-23 at 14.30.46.mp4…

Thanks again for the finding and apologies, but there will be a slight delay in other issues as some unpredictable things I have to deal with now have happened in my regular work 😉

@FulcrumOne FulcrumOne mentioned this issue May 30, 2024
FulcrumOne added a commit that referenced this issue May 30, 2024
fix:
- Fixed a problem with the safe area for BottomPopup (#97)
- Fixed a problem where the library was modifying the source view (#100)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants