iOS 26 Liquid Glass Gotcha: Adjacent Buttons Silently Swallowing Taps
Source: Dev.to
The Setup
Two buttons stacked vertically, 26 pt apart, using a standard VStack layout:
VStack(spacing: 26) {
Spacer()
Button {
store.send(.signupButtonTapped)
} label: {
Text("Sign Up")
.padding()
.frame(width: buttonWidth, height: 55)
}
.glassEffect(.clear.interactive())
.buttonStyle(.plain)
Button {
store.send(.loginButtonTapped)
} label: {
Text("Log In")
.padding()
.frame(width: buttonWidth, height: 50)
}
.glassEffect(.clear.interactive())
.buttonStyle(.plain)
}

Sign Up works; Log In does nothing. The code and modifiers are identical—the only difference is their position.
The Cause
Calling .glassEffect(.clear.interactive()) without specifying a shape defaults the glass platter to a rectangle. In iOS 26, the Liquid Glass system automatically merges adjacent glass surfaces that are close together into a single interactive group.
When merged, the .interactive() gesture handler routes taps to the first view in the hierarchy—the Sign Up button in this case. The Log In button’s taps are silently consumed by the merged glass group and never reach its action.
The merging behavior is intentional (Apple wants glass elements to feel like one fluid surface), but the side‑effect on gesture routing makes debugging extremely difficult because there’s no visible error.
The Fix
Specify an explicit shape with the in: parameter:
// Before (broken)
.glassEffect(.clear.interactive())
// After (works)
.glassEffect(.clear.interactive(), in: .capsule)
Giving each button a distinct glass shape prevents the automatic merge, so each button receives its own gesture handler.
A Reusable Modifier
If you wrap glass effects in a ViewModifier for backward compatibility, be sure to include the shape:
struct GlassButtonModifier: ViewModifier {
func body(content: Content) -> some View {
if #available(iOS 26.0, *) {
content.glassEffect(.clear.interactive(), in: .capsule)
} else {
content
.background(.ultraThinMaterial, in: Capsule())
}
}
}
When to Watch Out
This issue will bite you whenever:
- Two or more
.glassEffect()views are adjacent (e.g., in aVStack,HStack, orZStack). - You’re using
.interactive()for press/bounce feedback. - You haven’t specified a shape with
in:.
It’s especially dangerous because the first button always works, so the problem may go unnoticed until a user reports a dead button.
TL;DR
| Variant | Shape (default) | Merge? | Tap behavior |
|---|---|---|---|
.glassEffect(.clear.interactive()) | rectangle | Yes | Only first button receives taps |
.glassEffect(.clear.interactive(), in: .capsule) | capsule | No | All buttons receive taps |
Always pass a shape to .glassEffect() when using .interactive() on adjacent views. Future you will thank present you.