Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftUI : [Unknown process name] CGAffineTransformInvert: singular matrix ERROR

Tags:

ios

swift

swiftui

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

like image 224
Aryan Avatar asked Aug 28 '20 08:08

Aryan


2 Answers

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

like image 107
Debashish Das Avatar answered Nov 17 '22 12:11

Debashish Das


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

demo

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()
        }
    }
}
like image 32
Asperi Avatar answered Nov 17 '22 10:11

Asperi