Home > OS >  Updating a path before Animating it in SwiftUI
Updating a path before Animating it in SwiftUI

Time:12-27

I am trying to animate my path with a move value, It works almost, but the needed update to path happens after animation is done! Which must happen before Animation! How can I make it possible?

PS: The issue is about Path, and I am trying solve it through path.

struct HatchedShap: Shape {
    
    let dis: CGFloat
    var move: CGFloat
    
    var animatableData: CGFloat {
        get { return move }
        set { move = newValue }
    }

    func path(in rect: CGRect) -> Path {
        return Path { path in

            for index in -Int(move*2.0)...Int((rect.height)/dis) {
                
                path.move(to: CGPoint(x: rect.minX, y: rect.minY   (CGFloat(index)   move)*dis))
                path.addLine(to: CGPoint(x: rect.maxX, y: rect.minY   (CGFloat(index)   move)*dis))
                
            }
            
        }
    }
    
}

use case:

struct ContentView: View {
    
    @State private var move: CGFloat = CGFloat()

    var body: some View {

        HatchedShap(dis: 20.0, move: move)
            .stroke(Color.red, style: StrokeStyle(lineWidth: 2.0))
            .background(Color.black)
            .frame(width: 100, height: 200)
            .onTapGesture {
  
                if (move == -0.5) { move = 0}
                else { move = -0.5 }
            }
            .animation(Animation.linear(duration: 1.0), value: move)

    }
    
}

enter image description here

CodePudding user response:

I think using Factor of -0.5 Factor of -2


Small note:

You can simplify:

if (move == -0.5) {
    move = 0
} else {
    move = -0.5
}

To the following, which removes duplication & possibly faster because there is no branching (depends on if the compiler optimizes this):

move = -0.5 - move

CodePudding user response:

In your path code, assign y to a let constant and check to make sure it is larger than 0 before adding the line to the path:

struct HatchedShap: Shape {
    
    let dis: CGFloat
    var move: CGFloat
    
    var animatableData: CGFloat {
        get { return move }
        set { move = newValue }
    }

    func path(in rect: CGRect) -> Path {
        return Path { path in

            for index in -Int(move*2.0)...Int((rect.height)/dis) {
                let y = rect.minY   (CGFloat(index)   move)*dis
                if y > 0 {
                    path.move(to: CGPoint(x: rect.minX, y: y))
                    path.addLine(to: CGPoint(x: rect.maxX, y: rect.minY   (CGFloat(index)   move)*dis))
                }
                
            }
            
        }
    }
    
}
  • Related