I am trying to design a video trimmer view in SwiftUI as follows. This result is this. My question is whether I can have the middle part (i.e. everything except 20 points on the left and right and 5 points up and down) transparent so that I can show thumbnails behind them (perhaps by having a custom clip shape)?
var body: some View {
HStack(spacing: 10) {
Image(systemName: "chevron.compact.left")
.frame(height:70)
Spacer()
Image(systemName: "chevron.compact.right")
}
.foregroundColor(.black)
.font(.title3.weight(.semibold))
.padding(.horizontal, 7)
.padding(.vertical, 3)
.background(.yellow)
.clipShape(RoundedRectangle(cornerRadius: 7))
.frame(width: 300)
.onGeometryChange(for: CGFloat.self) { proxy in
proxy.size.width
} action: { width in
print("width = (width)")
}
}
2
Answers
Instead of
background
and thenclipShape
, usebackground(_:in:fillStyle:)
. This allows you to specify aShape
in which you want the background color to fill.You can write a
Shape
like this:I am simply subtracting the path created by an insetted rounded rectangle from a non-insetted one.
Then
subtracting
is available since iOS 17. If you need to support a lower version, you can just add the smaller rounded rectangle as a subpath, but use even-odd filling.Another way to cut out part of the background is to use an overlay with
.blendMode(.destinationOut)
. It is also necessary to apply.compositingGroup()
to the result, to prevent the blend mode burning into deeper layers.Replace these modifiers:
with:
You mentioned in a comment to the answer you already accepted that you would like the chevrons to look centered. Since you are applying padding of 7 at the sides, this means applying padding (or spacing) of 7 on the inner side too.
One way to achieve this is would be to move the chevrons into the overlay. Then in fact the whole view can be simplified: