I have a view, DotView
, which consists of 3 green circles
The green circles disappear.
The green circles stay.
The green circles stay.
Here's my code:
/// 3 green circles, constrained to a red border
struct DotView: View {
var body: some View {
HStack {
ForEach(0..<3) { _ in
Circle()
.fill(Color.green)
.frame(width: 100, height: 100)
}
}
.frame(width: 250)
.border(Color.red)
.clipped() /// 1. make sure the green circles don't overflow
}
}
/// container for horizontal dragging, with a blue border
struct ContentView: View {
@State var offset = CGFloat(0)
var body: some View {
DotView()
.padding() /// add a small gap between the red and blue borders
.offset(x: offset, y: 0)
.border(Color.blue)
.clipped() /// 2. make sure `DotView` doesn't overflow the blue border
.gesture(
DragGesture(minimumDistance: 0) /// slide `DotView` left and right
.onChanged { offset = $0.translation.width }
)
}
}
The disappearing effect is very visible with ForEach
, but occurs with other views too. For example, here's what happens when you replace the entire HStack
with Circle().fill(Color.green).frame(width: 100, height: 100)
:
Is there any way I can use clipped
more than once, without getting weird side effects? How come they only disappear on the left side and not the right side?
Or maybe, offset
is what's causing problems?
CodePudding user response:
Looks like drawing optimisation (and yes looks like it originated by offset
).
Anyway, here is a fix - use drawing group to fix content (tested with Xcode 13 / iOS 15):
var body: some View {
DotView()
.padding()
.drawingGroup() // << here !!
.offset(x: offset, y: 0)
.border(Color.blue)
.clipped()
.gesture(
DragGesture(minimumDistance: 0) /// slide `DotView` left and right
.onChanged { offset = $0.translation.width }
)
}