I am trying to add "accessory buttons" to a view. These buttons would appear when I hover over that view with a mouse pointer. The center of these buttons should coincide with a corner of the view.
Here is my attempt at positioning a button at the top trailing corner of a rectangle
struct ContentView: View {
@State private var hovering = false
var body: some View {
Rectangle()
.fill(.gray)
.frame(width: 100, height: 100)
.overlay(alignment: .topTrailing) {
if hovering {
Button { } label: {
Image(systemName: "eye.slash")
}
.alignmentGuide(HorizontalAlignment.trailing) { $0[HorizontalAlignment.center] }
.alignmentGuide(VerticalAlignment.top) { $0[VerticalAlignment.center] }
}
}
.controlSize(.small)
.buttonBorderShape(.circle)
.onHover {
hovering = $0
}
}
}
This produces
But the expected result is
I had thought that the alignmentGuide
s I added to the button would shift the center of the button to the top trailing corner of the rectangle, but they didn't do anything at all.
How do I achieve the desired appearance without hardcoding magic numbers for offsetting/padding the views?
It turns out alignmentGuide
s do work, if they are modifying the if hovering
statement. Obviously you cannot modify an if statement directly, so you have to wrap it with a Group
first.
.overlay(alignment: .topTrailing) {
Group {
if hovering {
Button { } label: {
Image(systemName: "eye.slash")
}
}
}
.alignmentGuide(HorizontalAlignment.trailing) { $0[HorizontalAlignment.center] }
.alignmentGuide(VerticalAlignment.top) { $0[VerticalAlignment.center] }
}