2.5 C
London
Sunday, March 3, 2024

ios – Matched geometry impact would not animate appropriately


I’ve a video participant that’s embedded inside a scroll view inside a subview. When the video participant is clicked I need to animate the video participant to the highest of the view hierarchy and current it above all the things else utilizing a matched geometry impact. I can not get the animation to work and as a substitute the video is instantly introduced.

My method is passing the AVPlayer and url by way of an setting object and utilizing the url because the id for geo impact.

struct SomeView: View { // subview
    let instance = "instance https://drive.google.com/file/d/1fom7lDNjP7thxTuowYtsUXbErvX2jhzH/view?usp=sharing"
    
    var physique: some View {
        ScrollView {
            BottomVideoView(url: URL(string: instance)!)
            //some views
        }
    }
}
struct ContentView: View { //prime of view hierarchy
     @EnvironmentObject var popRoot: PopToRoot
     @Namespace personal var animation
     var physique: some View {
          SomeView()
             .overlay {
                    if popRoot.participant != nil {
                        TopVideoView(participant: $popRoot.participant)
                            .matchedGeometryEffect(id: popRoot.playID, in: animation)
                            // ----- HERE 
                    }
             }
     }
}
class PopToRoot: ObservableObject { //envirnment object to be accessed wherever
    @Printed var participant: AVPlayer? = nil
    @Printed var playID: String = ""
}

video participant that goes above all the things

struct TopVideo: View {
    @Binding var participant: AVPlayer?

    var physique: some View {
        ZStack(alignment: .topTrailing){
            Shade.black
            if let vid = participant {
                VStack {
                    Spacer()
                    VidPlayer(participant: vid).aspectRatio(contentMode: .match)
                    Spacer()
                }
            }
            Button(motion: {
                withAnimation {
                    participant = nil
                }
            }, label: {
                Picture(systemName: "xmark").foregroundStyle(.white).font(.headline)
            }).padding(.trailing, 20).padding(.prime, 80)
        }
        .ignoresSafeArea()
    }
}

struct TopVideoView: View {
    @Binding var participant: AVPlayer?
    @State personal var hostingController: UIHostingController<TopVideo>? = nil

    func showImage() {
        let swiftUIView = TopVideo(participant: $participant)
        hostingController = UIHostingController(rootView: swiftUIView)
        hostingController?.view.backgroundColor = .clear
        hostingController?.view.body = CGRect(
            x: 0,
            y: 0,
            width: UIScreen.principal.bounds.width,
            peak: UIScreen.principal.bounds.peak)

        if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
           let window = windowScene.home windows.first {
            window.addSubview(hostingController!.view)

            hostingController?.view.heart.x = window.heart.x
        }
    }

    func dismissImage() {
        hostingController?.view.removeFromSuperview()
        hostingController = nil
    }

    var physique: some View {
        VStack {}
            .onAppear { showImage() }
            .onDisappear { dismissImage() }
    }
}

video participant in subview

struct BottomVideoView: View {
    @EnvironmentObject var popRoot: PopToRoot
    let url: URL
    @State var participant: AVPlayer? = nil
    @Namespace personal var animation
    
    var physique: some View {
        ZStack {
            if let vid = participant {
                VidPlayer(participant: vid)
                    // ----- HERE
                    .matchedGeometryEffect(id: url.absoluteString, in: animation)
                    .onTapGesture {
                        withAnimation {
                            popRoot.playID = url.absoluteString
                            popRoot.participant = participant
                        }
                    }
            }
        }
        .onAppear {
            if participant == nil {
                participant = AVPlayer(url: url)
            }
            self.participant?.play()
        }
    }
}

struct VidPlayer : UIViewControllerRepresentable {
    var participant : AVPlayer
    
    func makeUIViewController(context: UIViewControllerRepresentableContext<VidPlayer>) -> AVPlayerViewController {
        let controller = AVPlayerViewController()
        controller.participant = participant
        controller.showsPlaybackControls = false
        controller.allowsVideoFrameAnalysis = false
        return controller
    }
    
    func updateUIViewController(_ uiViewController: AVPlayerViewController, context: UIViewControllerRepresentableContext<VidPlayer>) { }
}

Latest news
Related news

LEAVE A REPLY

Please enter your comment!
Please enter your name here