SwiftUI add inverted mask

前端 未结 5 1227
醉话见心
醉话见心 2020-12-15 22:53

I\'m trying to add a mask to two shapes such that the second shape masks out the first shape. If I do something like Circle().mask(Circle().offset(…)), this has

5条回答
  •  悲&欢浪女
    2020-12-15 23:02

    I haven't tested this yet, but could you do something like this:

    extension UIView {
        func mask(_ rect: CGRect, invert: Bool = false) {
            let maskLayer = CAShapeLayer()
            let path = CGMutablePath()
    
            if (invert) {
                path.addRect(bounds)
            }
            path.addRect(rect)
            maskLayer.path = path
    
            if (invert) {
                maskLayer.fillRule = CAShapeLayerFillRule.evenOdd
            }
    
            // Set the mask of the view.
            layer.mask = maskLayer
        }
    }
    
    struct MaskView: UIViewRepresentable {
        @Binding var child: UIHostingController
        @Binding var rect: CGRect
        @Binding var invert: Bool
    
        func makeUIView(context: UIViewRepresentableContext) -> UIView {
            let view = UIView()
    
            self.child.view.mask(self.rect, invert: self.invert)
    
            view.addSubview(self.child.view)
    
            return view
        }
    
        func updateUIView(_ uiView: UIView, context: UIViewRepresentableContext) {
    
        }
    }
    

    Usage:

    struct ImageView: View {
        var body: some View {
            Image("image1")
        }
    }
    
    struct ContentView: View {
        @State var child = UIHostingController(rootView: ImageView())
        @State var rect: CGRect = CGRect(x: 50, y: 50, width: 50, height: 50)
        @State var invert: Bool = false
    
        var body: some View {
            VStack(alignment: .leading) {
                MaskView(child: self.$child, rect: self.$rect, invert: self.$invert)
            }
        }
    }
    

提交回复
热议问题