How do I align the Color
views in a straight line with the text to the side?
To look like so (text aligned leading):
█ red
█ green
█ blue
Or this (text aligned center):
█ red
█ green
█ blue
Current code:
struct ContentView: View {
@State private var colorName: Colors = .red
var body: some View {
Picker("Select color", selection: $colorName) {
ForEach(Colors.allCases) { color in
HStack {
color.asColor.aspectRatio(contentMode: .fit)
Text(color.rawValue)
}
}
}
}
}
enum Colors: String, CaseIterable, Identifiable {
case red
case green
case blue
var id: String { rawValue }
var asColor: Color {
switch self {
case .red: return .red
case .green: return .green
case .blue: return .blue
}
}
}
Result (not aligned properly):
Without the Picker
, I found it is possible to use alignmentGuide(_:computeValue:)
to achieve the result. However, this needs to be in a Picker
.
Attempt:
VStack(alignment: .custom) {
ForEach(Colors.allCases) { color in
HStack {
color.asColor.aspectRatio(contentMode: .fit)
.alignmentGuide(.custom) { d in
d[.leading]
}
Text(color.rawValue)
.frame(maxWidth: .infinity)
.fixedSize()
}
}
.frame(height: 50)
}
/* ... */
extension HorizontalAlignment {
struct CustomAlignment: AlignmentID {
static func defaultValue(in context: ViewDimensions) -> CGFloat {
return context[HorizontalAlignment.leading]
}
}
static let custom = HorizontalAlignment(CustomAlignment.self)
}
Result of attempt:
Label
, which I switched because I didn't know how someone might solve the problem. Although this mostly solves the problem, it would be nice to have something centered and uses something like alignment guides so I don't need to hardcode any sizes. In reality I have a lot more items than this, it's just a minimal example. Thank you for answering though! Basically the widest item in the picker would stay, and everything else is aligned to that. – Lenzi