swiftuilazyvgrid

How to update UILabel inside ForEach loop in SwiftUI and avoid 'No exact matches in reference to static method 'buildExpression'' error?


I'm trying to create a list of circles in SwiftUI that display different strings of text. To achieve this, I'm using a ForEach loop that creates a UILabel for each string and sets its text, font size, and number of lines accordingly. However, I keep getting the error 'No exact matches in reference to static method 'buildExpression'' on each of the lines where I try to update the label. What could be causing this error and how can I update the labels correctly inside the loop?

            // display the clickable circles in a grid layout
        LazyVGrid(columns: [GridItem(.adaptive(minimum: 80))], spacing: spacing) {
            ForEach(page.ageGroups, id: \.self) { group in
                let label = UILabel()
                label.text = group // <<<<< here comes error message
                label.font = UIFont.systemFont(ofSize: 20, weight: .bold)
                label.numberOfLines = 0 // allow the text to wrap to multiple lines
                label.sizeToFit()
                let diameter = max(label.bounds.width + 20, 40)
                Circle()
                    .fill(selectedGroups.contains(group) ? page.clickedColor : page.nonclickedColor) // change fill color based on whether the circle is clicked or not
                    .frame(width: diameter, height: diameter)
                    .overlay(Text(group)
                                .font(.system(size: diameter / 2.5, weight: .bold, design: .rounded))
                                .foregroundColor(.white)
                                .multilineTextAlignment(.center)
                                .frame(width: diameter - 10, height: diameter - 10)) // display the age group text and adjust the font size to fit inside the circle
                    .onTapGesture { toggleSelection(group: group) } // toggle the selection state of the age group
            }
        }

Solution

  • You are mixing UIKit and SwiftUI. I'm not fully sure what you want to achieve but here is a pure SwiftUI code for a start:

    struct ContentView: View {
        
        let ageGroups = ["0-5", "6-10", "11-17", "18-22", "23-25", "26-30", "30-39", "40-49", "50-59", "60-69", "70+"]
        
        @State private var  selectedGroups: Set<String> = []
        
        var body: some View {
            
            LazyVGrid(columns: [GridItem(.adaptive(minimum: 80))], spacing: 20) {
                ForEach(ageGroups, id: \.self) { group in
                    
                    Text(group)
                        .font(.system(size: 20, weight: .bold, design: .rounded))
                        .frame(width: 75, height: 75)
                    
                        .background(
                            Circle()
                                .fill(selectedGroups.contains(group) ? .blue : .gray)
                        )
                    
                        .onTapGesture {
                            if selectedGroups.contains(group) {
                                selectedGroups.remove(group)
                            } else {
                                selectedGroups.insert(group)
                            }
                        }
                }
            }
        }
    }
    

    enter image description here