我想让图像通过一个小矩形 100% 透明,对所有其他矩形 50% 透明。就好像打一个小孔来透视小矩形一样。这是我的代码...
struct ImageScope: View {
var body: some View {
ZStack {
Image("test_pic")
Rectangle()
.foregroundColor(Color.black.opacity(0.5))
Rectangle()
.frame(width: 200, height: 150)
.foregroundColor(Color.orange.opacity(0.0))
.overlay(RoundedRectangle(cornerRadius: 3).stroke(Color.white, lineWidth: 3))
}
}
}
为了更容易理解...
这是工作方法。它使用自定义形状和奇偶填充样式。
使用 Xcode 11.4 / iOS 13.4 进行测试
下面的演示具有更高的透明度对比度,以获得更好的可视性。
struct Window: Shape {
let size: CGSize
func path(in rect: CGRect) -> Path {
var path = Rectangle().path(in: rect)
let origin = CGPoint(x: rect.midX - size.width / 2, y: rect.midY - size.height / 2)
path.addRect(CGRect(origin: origin, size: size))
return path
}
}
struct ImageScope: View {
var body: some View {
ZStack {
Image("test_pic")
Rectangle()
.foregroundColor(Color.black.opacity(0.5))
.mask(Window(size: CGSize(width: 200, height: 150)).fill(style: FillStyle(eoFill: true)))
RoundedRectangle(cornerRadius: 3).stroke(Color.white, lineWidth: 3)
.frame(width: 200, height: 150)
}
}
}
使用
blendMode(.destinationOut)
,您不必绘制自定义形状,而且只需一行代码。有时添加 .compositingGroup()
修饰符是必要的。
ZStack {
Color.black.opacity(0.5)
Rectangle()
.frame(width: 200, height: 200)
.blendMode(.destinationOut) // << here
}
.compositingGroup()
为了清楚起见,该解决方案基于 eja08 的答案,但使用图像完全刷新。混合模式 .destinationOut 在黑色矩形中创建切口。嵌套的 ZStack 将图像放置在背景中,而不受混合模式的影响。
struct ImageScope: View {
var body: some View {
ZStack {
Image("test_pic")
ZStack {
Rectangle()
.foregroundColor(.black.opacity(0.5))
Rectangle()
.frame(width: 200, height: 150)
.blendMode(.destinationOut)
.overlay(RoundedRectangle(cornerRadius: 3).stroke(.white, lineWidth: 3))
}
.compositingGroup()
}
}
}
结果:
您可以将这个
.fill(opacity(0.0))
添加到形状中