0

I want to apply a custom transition on a set of views enclosed by a GeometryReader, as shown below:

(✔) Custom transition works:

    var body: some View {
    ZStack {
        VStack {
            VStack {
                ForEach(modelView.views) { view in
                    GeometryReader(content: { geometry in
                        RoundedRectangle(cornerRadius: 25.0)
                    })
                    .transition(.myCustomTransition) 
                    // Transition declared on the enclosing GeometryReader
                    // Custom transition works
                }
            }
        }
    }

(✗) Custom transition is ignored, gets defaulted to .opacity:

    var body: some View {
    ZStack {
        VStack {
            VStack {
                ForEach(modelView.views) { view in
                    GeometryReader(content: { geometry in
                        RoundedRectangle(cornerRadius: 25.0)
                            .transition(.myCustomTransition)
                        // Transition declared on the RoundedRectangle, as intended
                        // Custom transition gets replaced by an .opacity transition
                    })
                }
            }
        }
    }

Custom transitions on the RoundedRectangles work OK in the first block of code above where it's declared on the enclosing GeometryReader, but I can't structure it like this as I need the RoundedRectangles' current positioning data -which I have to get from the geometry var- to feed as an input to the custom transition. (This part was omitted from the above code for brevity, think of it like .myCustomTransition(param: aRequiredValueFromTheGeometryProxy)) So I need the transition to be declared inside the said GeometryReader like on the second example.

I cannot come up with any reason why the transitions on the second example wouldn't work as intended. I'm in no way an expert on SwiftUI, so I'm pretty sure I'm getting something wrong here.

Any ideas on why this happens and any possible workarounds would be greatly appreciated!

P.S. Rather unsurprisingly, adding an .transition(.identity) on the enclosing GeometryReader didn't work.

P.P.S. I did not include my custom transition implementation as it seems to be inconsequential to the problem. (i.e. When I replace the transition value with .slide, that doesn't work either)

Şafak Gezer
  • 3,928
  • 3
  • 47
  • 49
  • 2
    It behaves as designed. `RoundedRectangle` is instantly present in `GeometryReader` (which is just a kind of container), so transition does not work (because it works on insert/remove). You need to redesign internal of ForEach and move it onto separated row view, which conditionally onAppear would show rectangle and then transition would be activated. – Asperi Dec 15 '20 at 11:03
  • @Asperi Thank you for the insight! Maybe using values from the `GeometryReader` in custom transitions isn't great practice after all. – Şafak Gezer Dec 16 '20 at 08:02

0 Answers0