【问题标题】:SwiftUI - How to add foreground linear gradient on imageSwiftUI - 如何在图像上添加前景线性渐变
【发布时间】:2019-11-12 13:07:14
【问题描述】:

我找不到任何有关如何在 前景 上为我使用 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 修饰符,代码将完美运行。

【问题讨论】:

    标签: ios swift xcode macos swiftui


    【解决方案1】:

    这里的任务是在图像上显示渐变。为了在另一个视图上显示一个视图,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
    

    毕竟,我们需要对ZStack 应用frame 和padding 参数,以便渐变与图像大小相同。

    结果应该是这样的:

    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 的渐变,因为我们需要透明渐变来使图像可见。

    【讨论】:

    • 是否可以从顶部100px开始渐变?所以你会有一个 100px 的纯色然后渐变从那里淡出?
    • op 想要在前景(颜色)而不是背景(视图)上使用渐变
    【解决方案2】:

    这是因为foregroundColor 需要Color,但LinearGradient 是符合ShapeStyleView 协议的struct

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

    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)
    

    结果如下:

    【讨论】:

    • 很好的解决方案和例子!
    • 这段代码救了我的命!非常感谢你,伙计!
    【解决方案3】:

    同意@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)
        })
    }
    

    【讨论】:

    • .aspectRatio(contentMode: .fit) 不是必需的,但没关系。完美运行!
    猜你喜欢
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 2022-07-05
    • 1970-01-01
    • 1970-01-01
    • 2022-11-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多