Applying gradient to UIBezierPath in SwiftUI Shape

末鹿安然 提交于 2021-02-11 15:45:50

问题


I'm trying to accomplish the following:

struct MultiSegmentPaths: Shape {
  func path(in rect: CGRect) -> Path {
    let path1 = UIBezierPath()
    // apply gradient to path 1
    let path2 = UIBezierPath()
    // apply gradient to path 2

    return Path(path1.append(path2).cgPath)
  }
}

Now I thought I could wrap each segment with Path, but that returns some View which means I can't append the two together.

And applying a gradient directly to UIBezierPath requires having access to context - which isn't passed in via the path(CGRect) -> Path method.

Finally the reason for creating the two paths within the same Shape is because I need to scale them while maintaining their offsets to each other.


回答1:


The UIBezierPath(UIKIt) and Path(SwiftUI) are different things... To create Path you have to use its own instruments. Next, the fill operation (w/ gradient or anything) is drawing time operation, not part of path/shape creation.

Here is some example of combining to shapes filled by gradients. Tested with Xcode 11.4.

struct DemoShape1: Shape {
    func path(in rect: CGRect) -> Path {
        return Path { path in
            path.addRect(rect)
        }
    }
}

struct DemoShape2: Shape {
    func path(in rect: CGRect) -> Path {
        return Path { path in
            path.addArc(center: CGPoint(x: rect.midX, y: rect.midY), radius: rect.size.height/2, startAngle: Angle(degrees: 0), endAngle: Angle(degrees: 360), clockwise: true)
        }
    }
}

struct DemoCombinedShape: View {
    var gradient1 = LinearGradient(gradient: Gradient(colors:[.blue, .yellow]), startPoint: .top, endPoint: .bottom)
    var gradient2 = LinearGradient(gradient: Gradient(colors:[.red, .black]), startPoint: .leading, endPoint: .trailing)

    var body: some View {
        // both shapes are rendered in same coordinate space
        DemoShape1().fill(gradient1)
            .overlay(DemoShape2().fill(gradient2))
    }
}

struct TestCombinedShape_Previews: PreviewProvider {
    static var previews: some View {
        DemoCombinedShape()
            .frame(width: 400, height: 300)
    }
}


来源:https://stackoverflow.com/questions/61536686/applying-gradient-to-uibezierpath-in-swiftui-shape

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!