How can I break up the expression in my Swift UI code into distinct sub-expressions?

608 views Asked by At

How do I group my code to solve the error,

"The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions"

I have tried all other methods on Stack overflow, but they only cause more errors in my code. Note - The purpose of this page is to display information on different locations and provide a hero view (popup view) with further information when a location is selected.

Here is my code...

struct MainView : View {
            
            @State var topIndex = 0
            @State var index = 0
            @State var show = false
            @State var selectedIndex = 0
            // hero Animation....
            @Namespace var name
               
            var body: some View{
                
                ZStack {
                        Image("background1")
                            .resizable()
                            .scaledToFill()
                            .edgesIgnoringSafeArea(.all)
                    
                
                ZStack{
                    
                    VStack(spacing: 0){
                        
                        // tab view with tabs....
                        
                        // change tabs based on index...
                        
                        // Scroll View For Smaller Size Phones....
                        
                        ScrollView(UIScreen.main.bounds.height < 750 ? .vertical : .init(), showsIndicators: false) {
                            
                            VStack{
                                
                                
                                ScrollView(.horizontal, showsIndicators: false) {
                                    
                                    HStack(spacing: 30){
                                    
                                        }
                                    }
                                    .padding(.horizontal)
                                }
                                .padding(.top,60)
                                
                                // Vertical Menu...
                                
                                HStack{
                                    
                                    VerticalMenu()
                                        // moving view to left...
                                        .padding(.leading,-165)
                                        .zIndex(1)
                                    // moving view in stack for click event...
                                    
                                    // Scroll view....
                                    
                                    ScrollView(.horizontal, showsIndicators: false) {
                                        
                                        HStack(spacing: 15){
                                            
                                            ForEach(landmarkData, id: \.id) { landmark in
                                                
                                                ZStack(alignment: Alignment(horizontal: .center, vertical: .top)){
                            
                                                    VStack(alignment: .leading){
                                                        
                                                        Image(landmark.image)
                                                            .resizable()
                                                            .aspectRatio(contentMode: .fit)
                                                        // rotaing image....
                                                            .matchedGeometryEffect(id: landmark.image, in: name)
                                                        
                                                        Spacer(minLength: 0)
                                                        
                                                        Text(landmark.name)
                                                            .font(.system(size: 22))
                                                            .fontWeight(.bold)
                                                            .foregroundColor(.black)
                                                    
                                                        Spacer(minLength: 0)
                                                        
                                                        Text(landmark.category)
                                                            .foregroundColor(Color.white.opacity(0.6))
                                                        
                                                        Text(landmark.park)
                                                            .font(.system(size: 22))
                                                            .fontWeight(.bold)
                                                            .foregroundColor(.black)
                                                    }
                                                    
                                                    VStack(alignment: .leading){
                                                        
                                                        Image(landmark.image)
                                                            .resizable()
                                                            .aspectRatio(contentMode: .fit)
                                                        // rotaing image....
                                                            .matchedGeometryEffect(id: landmark.image, in: name)
                                                        
                                                        Spacer(minLength: 0)
                                                        
                                                        Text(landmark.name)
                                                            .font(.system(size: 22))
                                                            .fontWeight(.bold)
                                                            .foregroundColor(.black)
                                                    
                                                        Spacer(minLength: 0)
                                                        
                                                        Text(landmark.category)
                                                            .foregroundColor(Color.white.opacity(0.6))
                                                        
                                                        Text(landmark.city)
                                                            .font(.system(size: 22))
                                                            .fontWeight(.bold)
                                                            .foregroundColor(.black)
                                                    }
                                                }
                                                .padding(.horizontal)
                                                .padding(.vertical)
                                                // fixed Frame...
                                                .frame(width: UIScreen.main.bounds.width - 150, height: 360)
                                                .background(Color(.white))
                                                // opening hero animation...
                                                .onTapGesture {
                                                    
                                                    withAnimation(.spring()){
                                                        
                                                        selectedIndex = i
                                                        show.toggle()
                                                    }
                                                }
                                            }
                                        }
                                        .padding(.leading,20)
                                        .padding(.trailing)
                                    }
                                    .padding(.leading,-165)
                                }
                                // fixed height...
                                .padding(.top,30)
                                .frame(height: 400)
                                // when view is rotated width is converted to height,...
                                
                            
                                .padding(.top,25)
                                .padding(.horizontal)
                                
                                // Menu...
                                
                                }
                                .padding(.top,20)
                        .padding(.horizontal)
                                
                                Spacer(minLength: 0)
                                
                                
                            }
                            // since all edges are ignored....
                            .padding(.top,UIApplication.shared.windows.first?.safeAreaInsets.top)
                            .padding(.bottom)
                        }
                        
                        
                    
                    // Hero View....
                    
                    if show{
                        
                        VStack{
                            
                            VStack{
                                
                                HStack{
                                    
                                    Button(action: {}) {
                                        
                                        Image(systemName: "suit.heart")
                                            .font(.system(size: 22))
                                            .foregroundColor(.white)
                                    }
                                    
                                    Spacer()
                                    
                                    Button(action: {
                                        
                                        // closing hero view...
                                        
                                        withAnimation(.spring()){
                                            
                                            show.toggle()
                                        }
                                        
                                    }) {
                                        
                                        Image(systemName: "xmark")
                                            .font(.system(size: 22))
                                            .foregroundColor(.white)
                                    }
                                }
                                
                                Image(landmark.image)
                                    .resizable()
                                    .aspectRatio(contentMode: .fit)
                                    .frame(height: 250)
                                    .matchedGeometryEffect(id: landmark.image, in: name)
                                    .rotationEffect(.init(degrees: 12))
                                    .padding(.horizontal)
                            }
                            .padding()
                            .padding(.top,UIApplication.shared.windows.first?.safeAreaInsets.top)
                            .background(Color(.white))
                            
                            ScrollView(UIScreen.main.bounds.height < 750 ? .vertical : .init(), showsIndicators: false) {
                                
                                HStack{
                                    
                                    VStack(alignment: .leading, spacing: 10) {
                                        
                                        Text(landmark.category)
                                            .foregroundColor(.gray)
                                        
                                        Text(landmark.park)
                                            .font(.system(size: 22))
                                            .fontWeight(.bold)
                                            .foregroundColor(.black)
                                    }
                                    
                                    Spacer()
                                    
                                    Text(landmark.state)
                                        .font(.system(size: 22))
                                        .fontWeight(.bold)
                                        .foregroundColor(.black)
                                }
                                .padding()
                                
                                Text(landmark.imageName)
                                    .foregroundColor(.black)
                                    .padding(.top,20)
                                    .padding(.horizontal)
            
                            
                                    Spacer(minLength: 0)
                                
                                Spacer(minLength: 0)
                                
                                // Button...
                                
                                Button(action: {}) {
                                    
                                    Text("View on Live Map")
                                        .fontWeight(.bold)
                                        .padding(.vertical)
                                        .foregroundColor(.white)
                                        .frame(width: UIScreen.main.bounds.width - 100)
                                        .background(Color.black)
                                        .clipShape(Capsule())
                                }
                                .padding(.bottom,40)
                                .padding(.top)
                            }
                            
                        }
                        .background(Color.white)
                    }
            }
        }

    }
        
1

There are 1 answers

0
Asperi On BEST ANSWER

You should every logical sub-part in that huge block move into separated view. For example the entire horizontal scroll view can be separated and named HeaderView, so, instead of

VStack{
    ScrollView(.horizontal, showsIndicators: false) {
        HStack(spacing: 30){
                // ... other code            
            }
        }
        .padding(.horizontal)
    }
    .padding(.top,60)

you have

    VStack{
        HeaderView()
        // other code

and

struct HeaderView: View {
   var body: some View {
        ScrollView(.horizontal, showsIndicators: false) {
            
            HStack(spacing: 30){
            
                }
            }
            .padding(.horizontal)
        }
        .padding(.top,60)
   }
}

and in this way break & combine as far as possible.