I have a SwiftUI view for math expressions. It shows divisions as VStacks with a divider in the middle and additions as HStacks with a "+" sign in the middle. See the images in this GitHub gist: gist.github.com/Dev1an/668978dc4b84b8c6213ba10905d57c1d#proper-alignment
But I am having trouble aligning the Additions to the Divisions. I can create multiple custom alignment guides beforehand for each division and then everything works fine. But the problem is that I am generating these mathematical expressions dynamically and cannot create new guides (a Type conforming to
AlignmentID.Type) for every division in the expression. Is there a way to reuse alignment guides in nested views so that I can reuse the same custom VerticalAlignment multiple times?
When I try to reuse the same guide, the HStack's just align to the center (as shown in the gist).
Here is an example hierarchy:
Addition(alignment: .custom)
Division
Addition(alignment: .custom)
Number
+
Division
Number
/ (guide: .custom)
Number
/ (guide: .custom)
Number
+
NumberIs there an easy way to solve this? I think it should work a bit similar to VerticalAlign.firstBaseline but it should align to the first division guide down the view hierarchy (when traversing breadth-first) instead. So the Addition on line 01 should use the guide on line 10, and the Addition on line 03 should use the guide on line 08.
Any thoughts how to accomplish this?
@Claude31: Indeed your answer doesn't help me in any way. I don't care whether you can create custom views or not, I was asking people to help me build my own custom views. But anyway...
The VStack and HStack are actually quite a good match for this use case. The only thing I didn't understood yet was the way in which alignment guides were passed up the view hierarchy. I figured it out now and it turns out that I had to put the guide on the dividend instead of the divider line.
So to summarize, here is the code I ended up with:
struct AdditionView: View {
let left: Left
let right: Right
var body: some View {
HStack(alignment: .division) {
left
Text("+")
right
}
.fixedSize()
}
}
struct DivisionView: View {
let dividend: Dividend
let divisor: Divisor
let spacing: CGFloat = 3
var body: some View {
VStack(spacing: spacing) {
aligningDividend
Divider().overlay(Color.primary)
divisor
}
.fixedSize()
}
var aligningDividend: some View {
dividend.alignmentGuide(.division) { dividend in
dividend[.bottom] + self.spacing
}
}
}
extension VerticalAlignment {
private enum Divider: AlignmentID {
static func defaultValue(in context: ViewDimensions) -> CGFloat {
context[VerticalAlignment.center] + 1
}
}
static let division = Self(Divider.self)
}And that gives me nice and aligned divisions in additions 😎.