SwiftUI Button hit area extends ~16pt beyond its visual frame — expected OS behavior?
Hi everyone,
I’m working on a custom SwiftUI segmented control and noticed some unexpected hit-testing behavior with Button.
I have a button structured roughly like this:
Button {
selectItem(at: index)
} label: {
ZStack {
if selectedIndex == index {
selectedBackground
}
SegmentCellView(
tab: tab,
isSelected: selectedIndex == index
)
}
.frame(maxWidth: .infinity)
.contentShape(Rectangle())
}
.accessibilityLabel(Text(tab.labelText))
The visual frame of the button has a certain height, but when testing on a real device, I can tap approximately 16pt outside the button's visible frame and the button still receives the tap.
This seems to happen even though I explicitly use:
.contentShape(Rectangle())
to define the tappable shape.
My questions are:
- Is this ~16pt expansion of the interactive area expected SwiftUI/OS behavior?
- Is this related to Apple's minimum hit-target/accessibility guidelines being automatically applied to controls such as
Button? - If so, is there an official API/documentation describing this behavior?
- Is there a recommended way to make the
Button's hit-testing area exactly match the bounds defined by.contentShape(Rectangle()), if that is actually possible?
I'm particularly interested in understanding whether this is intentional system behavior or something caused by the ButtonStyle / layout hierarchy.
Thanks!