I would like to have a scroll view with a lot of subviews that have a custom location and can be touch-moved around by the user. They might also have some other controls in them (including text fields or even text editors). I tried the following:
struct CardThing: Identifiable {
let id: Int
let position: CGPoint
let label: String
}
let cards: [CardThing] = [
CardThing(id: 1, position: CGPoint(x: 00, y: 10), label: "Card one"),
CardThing(id: 2, position: CGPoint(x: 20, y: 20), label: "Card two"),
CardThing(id: 3, position: CGPoint(x: 40, y: 40), label: "Card three"),
CardThing(id: 4, position: CGPoint(x: 60, y: 60), label: "Card four"),
]
// The following view is a view of a graph structure.
//
struct ContentView: View {
var body: some View {
// The scroll view should be either virtually infinite
// or some auto-resizable based on content with reasonable
// margins. When margins are reached it is resized to maintain
// those margins. But that is not relevant to this question.
ScrollView {
// The content will usually be in couple of dozens or couple of hundreds
ForEach(cards) {
// Here it will be some kind of a card view in the future
Text($0.label)
// The position is explicit, should not undergo auto-layout
.position($0.position)
// Frames might also differ, should not undergo some auto-sizing
.frame(width: 320, height: 200)
.border(Color.green)
}
// The following will also be part of the view, but it is assumed
// that the answer to the original question will answer it. It is just
// here to provide more context about the idea of the view's content.
// ForEach(links) { ... display link as touchable line-like shape ... }
}
.frame(width:600, height: 400)
}
}
But the preview result looked automatically (mis-)aligned (also note the incomplete labels):
What I am doing wrong?