首页 > 解决方案 > 带有系统图像的倒置蒙版 swiftui

问题描述

我正在尝试从 swiftUI 中的圆形中剪下一个 sf 符号。

我目前有以下代码:

Circle()
   .fill(Color.white)
   .frame(width: 50, height: 50)
   .mask(
       Image(systemName: "play.fill")
           .font(.system(size: 24))
           .foregroundColor(Color.black)
           .frame(width: 50, height: 50)
   )

生成:

在此处输入图像描述

但是,我想要的是反转蒙版的效果:该符号从圆圈中切出,如下图所示:

在此处输入图像描述

请注意,实际背景不是图像中的红色,而是用户上传的图像,因此无法将符号 foregroundColor 设置为红色。

有什么方法可以反转符号/图像的蒙版,使圆圈中有一个带有图像形状的孔?

标签: iosswiftuisf-symbols

解决方案


对于抠图,只需使用.blendMode(.destinationOut).compositingGroup()。无需重复形状、遮盖它并定义白色/黑色。

var buttonCutOut: some View {
        ZStack {
            shape
            mask.blendMode(.destinationOut)
        }.compositingGroup()
    }

这是一个用于蒙版形状或亮度蒙版形状的示例可重用组件。

在此处输入图像描述


struct Demo: View {
    var body: some View {
        ZStack {
            userImage.blur(radius: 5)
            playButtons
        }
    }

    var playButtons: some View {
        VStack {
            Mask(thisShape: Circle(),
                 with: maskImage,
                 offset: maskImageOffset,
                 maskToShapeRatio: maskImageToShapeRatio)
                .frame(width: square, height: square)
                .foregroundColor(colorDestinationOut)

            LuminanceMask(thisShape: Circle(),
                          with: maskImage,
                          offset: maskImageOffset,
                          maskToShapeRatio: maskImageToShapeRatio)
                .frame(width: square, height: square)
                .foregroundColor(colorLuminanceAlpha)
        }
        .font(font)
    }
}

struct Mask<S: Shape>: View {
    init(thisShape: S,
         with mask: Image,
         offset: CGSize,
         maskToShapeRatio: CGFloat) {
        self.shape = thisShape
        self.mask = mask
        self.offset = offset
        self.scale = maskToShapeRatio
    }

    let shape: S
    let mask: Image
    let offset: CGSize
    let scale: CGFloat

    var body: some View {
        ZStack(alignment: .center) {
            shape.fill()
            mask
                .resizable()
                .offset(offset)
                .aspectRatio(contentMode: .fit)
                .blendMode(.destinationOut)
                .scaleEffect(scale)
        }.compositingGroup()
    }
}

struct LuminanceMask<S: Shape>: View {
    init(thisShape: S,
         with mask: Image,
         offset: CGSize,
         maskToShapeRatio: CGFloat) {
        self.shape = thisShape
        self.mask = mask
        self.offset = offset
        self.scale = maskToShapeRatio
    }

    let shape: S
    let mask: Image
    let offset: CGSize
    let scale: CGFloat

    let keep = Color.white
    let remove = Color.black

    var body: some View {
            shape.mask(maskView)
    }

    var maskView: some View {
        ZStack(alignment: .center) {
            shape
                .foregroundColor(keep)

            mask
                .resizable()
                .offset(offset)
                .aspectRatio(contentMode: .fit)
                .scaleEffect(scale)
                .foregroundColor(remove)

        }.compositingGroup()
        .luminanceToAlpha()

    }
}


推荐阅读