English 中文(简体)
配对的地貌效应与窗户的 t
原标题:Matched geometry effect doesn t work with window

我有一个广场,位于分门座的滚动观点内。 当对广场进行点击时,我想将其与地表层的顶层联系起来,并将其置于其他一切之外,使用相应的地表效应。 我不能 get。

Problem I present the square at the top of the view hierarchy through a window which makes the animation fail. How can I correctly animate with a window?

struct SomeView: View {
    @EnvironmentObject var popRoot: PopToRoot
    @Namespace private var animation
    var body: some View {
        ScrollView {
            RoundedRectangle(cornerRadius: 10)
                .matchedGeometryEffect(id: "squareAnim", in: animation)
                .foregroundStyle(.blue).frame(width: 50, height: 50)
                .onTapGesture {
                    withAnimation {
                        popRoot.showOverlay = true
                    }
                }
            //other sub views
        }
    }
}
struct ContentView: View { //top of view hierarchy
     @EnvironmentObject var popRoot: PopToRoot
     @Namespace private var animation
     var body: some View {
          SomeView()
             .overlay {
                    if showOverlay {
                        TopViewWindow()
                            .matchedGeometryEffect(id: "squareAnim", in: animation)
                            // ----- HERE
                    }
             }
     }
}

class PopToRoot: ObservableObject { //envirnment object to be accessed anywhere
    @Published var showOverlay = false
}

超越一切内容的视觉角色

video player that goes above everything

struct TopView: View {
    var body: some View {
        ZStack {
            RoundedRectangle(cornerRadius: 10)
                .foregroundStyle(.blue).frame(width: 100, height: 100)
            
            //other views
        }.ignoresSafeArea()
    }
}

struct TopViewWindow: View {
    @State private var hostingController: UIHostingController<TopView>? = nil

    func showImage() {
        let swiftUIView = TopView()
        hostingController = UIHostingController(rootView: swiftUIView)
        hostingController?.view.backgroundColor = .clear
        hostingController?.view.frame = CGRect(
            x: 0,
            y: 0,
            width: UIScreen.main.bounds.width,
            height: UIScreen.main.bounds.height)

        if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
           let window = windowScene.windows.first {
            // withAnimation { doesnt work here either
            window.addSubview(hostingController!.view)

            hostingController?.view.center.x = window.center.x
        }
    }
    func dismissImage() {
        hostingController?.view.removeFromSuperview()
        hostingController = nil
    }
    var body: some View {
        VStack {}.onAppear { showImage() }.onDisappear { dismissImage() }
    }
}
问题回答

你们应当确保在参与估算的各种不同观点中正确分享动画空间。 根据你的代码,在<代码>中似乎使用不同的名称空间。 观点,可能会使问题产生于未按预期行事的估算。

The namespace used for the matched geometry effect should be declared in a common ancestor view and passed down to all child views that need it. That way, the same animation namespace is used across your views.
The ID used with .matchedGeometryEffect (as described in "How to synchronize animations from one view to another with matchedGeometryEffect()" from Paul Hudson) needs to be consistent across both views participating in the animation. It looks like you are using popRoot.playID, which should work as long as it is correctly set before the animation starts.

页: 1 使用了UIHostingController,向视频播放,这可能会使相应的地貌效应复杂化。 页: 1 问答表最好在快速调查组的等级内进行,因此考虑将<代码>TopVideo直接纳入快速调查组的观点等级,而不是在窗口上添加。

class PopToRoot: ObservableObject { // Environment object accessible anywhere
    @Published var player: AVPlayer? = nil
    @Published var playID: String = ""
}

struct ContentView: View { // Top of the view hierarchy
    @EnvironmentObject var popRoot: PopToRoot
    @Namespace private var animationNamespace

    var body: some View {
        ZStack {
            SomeView(animation: animationNamespace)
            
            if popRoot.player != nil {
                TopVideo(player: $popRoot.player)
                    .matchedGeometryEffect(id: popRoot.playID, in: animationNamespace)
                    .ignoresSafeArea()
            }
        }
    }
}

struct SomeView: View { // Subview
    let example = "example URL"
    var animation: Namespace.ID

    var body: some View {
        ScrollView {
            BottomVideoView(url: URL(string: example)!, animation: animation)
            // Additional views
        }
    }
}

struct BottomVideoView: View {
    @EnvironmentObject var popRoot: PopToRoot
    let url: URL
    var animation: Namespace.ID
    @State var player: AVPlayer? = nil

    var body: some View {
        ZStack {
            if let vid = player {
                VidPlayer(player: vid)
                    .matchedGeometryEffect(id: url.absoluteString, in: animation)
                    .onTapGesture {
                        withAnimation {
                            popRoot.playID = url.absoluteString
                            popRoot.player = player
                        }
                    }
            }
        }
        .onAppear {
            if player == nil {
                player = AVPlayer(url: url)
                self.player?.play()
            }
        }
    }
}

// No changes needed for VidPlayer and TopVideo

The animationNamespace is declared in ContentView and passed to SomeView and BottomVideoView. That makes sure the matched geometry effect operates within the same namespace across these views. The TopVideo view is directly integrated into the SwiftUI view hierarchy, which should help with the animation.
Make sure the environment object (PopToRoot) is correctly passed down to all views that require access to it.





相关问题
List Contents of Directory in a UITableView

I am trying to list the contents of Ringtones directory in a TableView, however, I am only getting the last file in the directory in ALL cells, instead of file per cell. This is my code: - (...

iPhone NSUserDefaults persistance difficulty

In my app i have a bunch of data i store in the NSUserdefaults. This information consists of an NSObject (Object1) with NSStrings and NSNumbers and also 2 instances of yet another object (Object2). ...

Writing a masked image to disk as a PNG file

Basically I m downloading images off of a webserver and then caching them to the disk, but before I do so I want to mask them. I m using the masking code everyone seems to point at which can be found ...

Resize UIImage with aspect ratio?

I m using this code to resize an image on the iPhone: CGRect screenRect = CGRectMake(0, 0, 320.0, 480.0); UIGraphicsBeginImageContext(screenRect.size); [value drawInRect:screenRect blendMode:...

Allowing interaction with a UIView under another UIView

Is there a simple way of allowing interaction with a button in a UIView that lies under another UIView - where there are no actual objects from the top UIView on top of the button? For instance, ...

热门标签