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
}
}
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)
}
}
}
}
}
}