SwiftUI-如何在图像上添加前景线性渐变

wfsdck30  于 2022-09-19  发布在  Swift
关注(0)|答案(4)|浏览(233)

我找不到任何有关如何在前景上为我使用SwiftUI的图像进行线性渐变的相关文档。

我试着这样做:

Image("IconLoseWeight")
  .frame(width: 30.0, height: 30.0)
  .padding(.leading, 17)
  .foregroundColor(LinearGradient(gradient: Gradient(colors: [.white, .black]), startPoint: .top, endPoint: .bottom))

实际上,上面显示的代码没有显示任何错误,但它用顶级堆栈中毫无意义的警告破坏了代码(我认为这是Xcode或SwiftUI的错误)。如果删除foreground修饰符,代码将完美运行。

qhhrdooz

qhhrdooz1#

这是因为前景颜色需要Color,但LinearGradient是符合协议ShapeStyleViewstruct

如果我理解正确的话,你想用渐变来填充图像的不透明区域?

ZStack {
  Color.white // For the background. If you don't need a background, you don't need the ZStack.
  LinearGradient(gradient: Gradient(colors: [.green, .blue]), startPoint: .top, endPoint: .bottom)
    .mask(Image("AssetWithTransparency")
      .resizable()
      .padding()
      .aspectRatio(contentMode: .fit))
  }.cornerRadius(15)

结果看起来是这样的:

rn0zuynd

rn0zuynd2#

这里的任务是在图像上显示渐变。为了在另一个视图上显示一个视图,SwiftUI提供了ZStack视图,因此,代码可以具有下一个结构:

ZStack {
    <Image>
    <Rectangle with gradient>
}

此外,为了确保我们使用的图像的大小正确调整到指定的帧resizable,应该使用正确的contentMode应用修改器:

Image("IconLoseWeight")
    .resizable()                     // Make it resizable
    .aspectRatio(contentMode: .fit)  // Specifying the resizing mode so that image scaled correctly

毕竟,我们需要将frame和填充参数应用到ZStack,以便渐变具有与图像相同的大小。

结果将如下所示:

ZStack {
    Image("IconLoseWeight")
        .resizable()                    // Making the image resizable to the container size
        .aspectRatio(contentMode: .fit) // Setting up resizing mode so that the image scaled correctly

    Rectangle()                         // Shapes are resizable by default
        .foregroundColor(.clear)        // Making rectangle transparent
        .background(LinearGradient(gradient: Gradient(colors: [.clear, .black]), startPoint: .top, endPoint: .bottom), cornerRadius: 0)   
                                        // Specifying gradient (note that one color is .clear)
}
.frame(width: 30, height: 30)           // Applying frame
.padding(.leading, 17)                  // Applying padding

请注意,我们使用从.clear.black的渐变,因为我们需要一个透明的渐变来使图像可见。

gfttwv5a

gfttwv5a3#

同意@RyuX51的答案,它工作得很好。但我的图像的大小和对齐方式发生了一些变化。因为未设置LinearGradientframe
所以在这里我想出了一个解决方案,只需将渐变应用到Image

VStack{
    Spacer()
    Button(action: {
        print("Add Photos")
    }, label: {

        LinearGradient(gradient: Gradient(colors: [.green, .blue]), startPoint: .top, endPoint: .bottom)
            .mask(Image(systemName: "plus.circle.fill")
            .resizable()
            .aspectRatio(contentMode: .fit)
        ).frame(width: 70, height: 70, alignment: .center)
    })
}
rm5edbpk

rm5edbpk4#

要做到这一点,最新的SwiftUI版本的最佳方法是使用.foregroundStyle()视图修饰符。我不确定这种方法是什么时候出现的,但这段代码已经在Xcode14和iOS 16上进行了测试。

示例代码如下:

let gradient = Gradient(colors: [.purple, .cyan, .orange])

var body: some View {
    Image(systemName: "figure.strengthtraining.traditional")
        .font(.title)
        .foregroundStyle(.linearGradient(gradient, startPoint: .top, endPoint: .bottom))
}

相关问题