I am building a TagsView in SwiftUI, which can display words as tags. The basic implementation works but it cuts off the labels from the side. I am sure there is something wrong with my algorithm. Here is the screenshot:
And here is the complete code to create the TagsView. The code also includes test data.
struct TagsView: View {
let items: [String]
let screenWidth = UIScreen.main.bounds.width
var groupedItems: [[String]] = [[String]]()
var backgroundColor: Color
var foregroundColor: Color
init(items: [String], backgroundColor: Color = Color.blue, foregroundColor: Color = Color.white) {
self.items = ["iusto", "assumenda", "hic", "omnis", "labore", "dolorem", "aut", "aliquam", "voluptatibus", "et", "placeat", "soluta", "qui", "voluptatibus", "possimus", "velit", "eaque", "commodi", "dolor", "dicta", "cum", "aperiam", "hic", "maxime", "mollitia", "itaque", "molestiae", "nemo", "eligendi", "unde", "tempore", "sit", "velit", "qui", "ut", "praesentium", "fugit", "velit", "error", "aut", "nulla", "est", "est", "similique", "aut", "laborum", "dolorem", "voluptatem", "nobis", "quaerat"]
self.backgroundColor = backgroundColor
self.foregroundColor = foregroundColor
groupedItems = createGroupedItems(items)
}
private func createGroupedItems(_ items: [String]) -> [[String]] {
var groupedItems: [[String]] = [[String]]()
var tempItems: [String] = [String]()
var width: CGFloat = 0
for word in items {
let label = UILabel()
label.text = word
label.sizeToFit()
let viewWidth = label.frame.size.width
print("viewWidth = \(viewWidth)")
if (width + viewWidth) < screenWidth {
width += viewWidth
print("width = \(width)")
tempItems.append(word)
} else {
print("ELSE")
width = viewWidth
groupedItems.append(tempItems)
tempItems.removeAll()
tempItems.append(word)
print(tempItems)
}
}
groupedItems.append(tempItems)
return groupedItems
}
var body: some View {
ScrollView {
VStack(alignment: .leading) {
ForEach(groupedItems, id: \.self) { subWords in
HStack {
ForEach(subWords, id: \.self) { word in
Text(word)
.fixedSize()
.padding()
.background(backgroundColor)
.foregroundColor(foregroundColor)
.clipShape(RoundedRectangle(cornerRadius: 10.0, style: /*@START_MENU_TOKEN@*/.continuous/*@END_MENU_TOKEN@*/))
}}
}
Spacer()
}.padding()
}
}
}
