Expectation: Green dot loading animation to occur when tapped on heart icon
Outcome: Nothing happens, feels like it freezes since the heart animation also doesn't work
Error: [Unknown process name] CGAffineTransformInvert: singular matrix.
Screenshot of the app(not working state)
Code:
struct ContentView: View {
@State private var count=0
@State var isPressed = false
@State var pressed = false
@State var isLoading = false
var body: some View {
VStack {
ZStack{
Circle()
.fill( isPressed ? Color(.systemGray4) : .red )
.overlay(Image(systemName:"heart.fill")
.foregroundColor(isPressed ? .red :.white)
.font(.system(size:100))
.scaleEffect( pressed ? 1.5 : 1.0)
)
.frame(width: 300, height: 300)
}
.onTapGesture{
self.isLoading.toggle()
withAnimation(.spring(response: 1,dampingFraction: 0.4, blendDuration :0.9)){
self.isPressed.toggle()
self.pressed.toggle()
self.isLoading.toggle()
}
}
HStack{
ForEach(0...4, id: \.self){index in
Circle()
.frame(width:10,height:10)
.foregroundColor(.green)
.scaleEffect(self.isLoading ? 1:0)
.animation(Animation.linear(duration:0.6).repeatForever().delay(0.2*Double(index)))
}
}
.padding()
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Note: Loading animation works when I don't toggle the isLoading
state variable inside onTapGesture()
block and directly set it to true when the view appears inside onAppear()
block
REASON :
The problem is basically with CGAffinTransform
When you use the modifier ScaleEffect to your view, in background the compiler performs some short of Transforms on the scale Value that you have provided.
Since you have provided value 0 (zero) for .scaleEffect(), its taking the size as zero and treating it as a singular Matrix ( its a type of matrix whose Determinant is Zero ). and its also considered a mathematical violation to perform operations on matrices with a determinant of zero.
SOLUTION :
Make sure if you are using .scaleEffect() , don't scale the View to exact 0. You can use the smallest possible value i.e 0.1 or 0.01
The problem is in 0
scaleEffect.
Here is fixed code. Tested with Xcode 11.4 / iOS 13.4. Also corrected animation for the case of isLoading = false
struct ContentView: View {
@State private var count=0
@State var isPressed = false
@State var pressed = false
@State var isLoading = false
var body: some View {
VStack {
ZStack{
Circle()
.fill( isPressed ? Color(.systemGray4) : .red )
.overlay(Image(systemName:"heart.fill")
.foregroundColor(isPressed ? .red :.white)
.font(.system(size:100))
.scaleEffect( pressed ? 1.5 : 1.0)
)
.frame(width: 300, height: 300)
}
.onTapGesture{
self.isLoading.toggle()
withAnimation(.spring(response: 1,dampingFraction: 0.4, blendDuration :0.9)){
self.isPressed.toggle()
self.pressed.toggle()
}
}
HStack{
ForEach(0...4, id: \.self){index in
Circle()
.frame(width:10,height:10)
.foregroundColor(.green)
.scaleEffect(self.isLoading ? 1:0.01)
.animation(self.isLoading ? Animation.linear(duration:0.6).repeatForever().delay(0.2*Double(index)) :
.default
)
}
}
.padding()
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With