Skip to content

Instantly share code, notes, and snippets.

@tomasen
Last active December 25, 2021 16:36
Show Gist options
  • Save tomasen/2f25e50ff6c72bc045d2b8bfcf0b352b to your computer and use it in GitHub Desktop.
Save tomasen/2f25e50ff6c72bc045d2b8bfcf0b352b to your computer and use it in GitHub Desktop.
WordSizeGetter in WordCloudView demo
struct WordCloudView: View {
private let words: [WordElement] = [WordElement].generate(forSwiftUI: true)
@State private var canvasRect = CGRect()
@State private var wordSizes: [CGSize]
init() {
self._wordSizes = State(initialValue:[CGSize](repeating: CGSize.zero, count: words.count))
}
var body: some View {
let pos = calcPositions(canvasSize: canvasRect.size, itemSizes: wordSizes)
return ZStack{
ForEach(Array(words.enumerated()), id: \.offset) {idx, word in
NavigationLink(destination: Text("\(word.text)")) {
Text("\(word.text)")
.foregroundColor(Color(word.color))
.font(Font.custom(word.fontName,
size:word.fontSize))
.lineLimit(1)
.fixedSize(horizontal: false, vertical: true)
.padding(3)
.background(WordSizeGetter($wordSizes, idx))
}
.position(x: canvasRect.width/2 + pos[idx].x,
y: canvasRect.height/2 + pos[idx].y)
}
}
.background(RectGetter($canvasRect))
}
func calcPositions(canvasSize: CGSize, itemSizes: [CGSize]) -> [CGPoint] {
var pos = [CGPoint](repeating: CGPoint.zero, count: itemSizes.count)
if canvasSize.height == 0 {
return pos
}
// ...
}
}
struct WordSizeGetter: View {
@Binding var sizeStorage: [CGSize]
private var index: Int
init(_ sizeStorage: Binding<[CGSize]>, _ index: Int) {
_sizeStorage = sizeStorage
self.index = index
}
var body: some View {
GeometryReader { proxy in
self.createView(proxy: proxy)
}
}
func createView(proxy: GeometryProxy) -> some View {
DispatchQueue.main.async {
self.sizeStorage[index] = proxy.frame(in: .global).size
}
return Rectangle().fill(Color.clear)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment