Home > database >  Failed to produce diagnostic for expression; please file a bug report
Failed to produce diagnostic for expression; please file a bug report

Time:12-01

I'm trying to make calculator, but I got this error when I try to make buttons from array, I followed some tutorial, then it's worked, when I tried on my own, code won't compile as it should. here is some code

struct ContentView: View {
    let value = """
            modern
            calculator
            """
    
    let numbers = [ "7", "8", "9",
                    "4", "5", "6",
                    "1", "2", "3" ]
    
    var body: some View {
        VStack{
            VStack{
                Text(value.self)
                    .fontWeight(.thin)
                    .multilineTextAlignment(.trailing)
                    .frame(width: 416, height: 420)
                    .font(.system(size: 70))
                    .foregroundColor(Color.white)
                 

            }.frame(minWidth: 0,  maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .topLeading).background(Color.blue)
            VStack{
                Spacer(minLength: 48)
                VStack{
                    
                
                ForEach(numbers, id:\.self) {
                    number in
                    HStack{
                        Spacer(minLength: 13)

                        ForEach(number, id:\.self){
                            num in
                            
                            Button(action: {}, label: {
                                Text(num).font(.largeTitle).fontWeight(.thin)
                                    .frame(width: 50, height: 50)
                                                .foregroundColor(Color.black)
                                                .background(Color.white)
                                                .clipShape(Circle())
                            })
                        }
                        
            
                    }
                }
                }
            }.frame(minWidth: 0,  maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .topLeading).background(Color.black)
        }.edgesIgnoringSafeArea(/*@START_MENU_TOKEN@*/.all/*@END_MENU_TOKEN@*/)
    }
}

Error is on line 20, when I get rid of this part:

ForEach(number, id:\.self){
                            num in
                            Button(action: {}, label: {
                                Text(num).font(.largeTitle).fontWeight(.thin)
                                    .frame(width: 50, height: 50)
                                                .foregroundColor(Color.black)
                                                .background(Color.white)
                                                .clipShape(Circle())
                            })
                        }

code compile. I want to make this buttons dymanic, just for practice.

CodePudding user response:

I presume that because you want a calculator, you were attempting to make a grid with the second ForEach. In order to do that, you would need to put a [[String]], or whatever type you were using. But there is a much simpler solution in using a LazyVGrid().

Also, you need to pick a style with your view modifiers and stick with it. Either run them on one line or use multi-line. Otherwise you will miss things. I would recommend multi-line as it makes your code easy to read as a SwiftUI beginner.

There are quite a few tutorials on making a calculator, and I would follow them. Handling button pushes and making decimal numbers can be more difficult than you think. But, for your UI code:

struct ContentView: View {
    let value = """
            modern
            calculator
            """
    // Added a "." as you will need that button.
    let calcButtons = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "."]
    
    let columns = [
        // Using 3 grid items forces there to be 3 columns
        GridItem(.adaptive(minimum: 80)),
        GridItem(.adaptive(minimum: 80)),
        GridItem(.adaptive(minimum: 80))
    ]
    
    var body: some View {
        VStack{
            Text(value.self)
                .fontWeight(.thin)
                .multilineTextAlignment(.trailing)
                .font(.system(size: 70))
                .foregroundColor(Color.white)
            
            LazyVGrid(columns: columns, spacing: 20) {
                ForEach(calcButtons, id: \.self) { calcButton in
                    Text(calcButton)
                        .fontWeight(.thin)
                        .font(.system(size: 70))
                        .foregroundColor(Color.white)
                        .background(
                            // Colored red so you can see the size of the buttons. If you remove this, your button
                            // will be the width of the text which varies making the buttons hard to tap.
                            // Change the color to .clear to make a hidden background.
                            Color.red
                                .frame(width: 80, height: 80)
                        )
                }
            }
        }
        .background(Color.blue
                        .edgesIgnoringSafeArea(.all)
        )
        
    }
}
  • Related