SwiftUI中的自定义交叉阴影背景形状或视图
我正在尝试创建一个阴影交叉阴影。但到目前为止,我可以通过添加图像来实现 如何创建一个自定义视图,在该视图中绘制线而不填充图像SwiftUI中的自定义交叉阴影背景形状或视图,swiftui,draw,shapes,Swiftui,Draw,Shapes,我正在尝试创建一个阴影交叉阴影。但到目前为止,我可以通过添加图像来实现 如何创建一个自定义视图,在该视图中绘制线而不填充图像 import SwiftUI struct ContentView: View { var body: some View { ZStack { Image("lineFilledBG").resizable().clipShape(Circle()) Circle().str
import SwiftUI
struct ContentView: View {
var body: some View {
ZStack {
Image("lineFilledBG").resizable().clipShape(Circle())
Circle().stroke()
Circle().foregroundColor(.yellow).opacity(0.3)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
这就是现在的样子。希望在另一个视图或形状的顶部绘制线条,而不添加不透明度和图像填充图案
我不确定这是否是您想要的,但CoreImage可以生成剥离图案
import CoreImage.CIFilterBuiltins
import SwiftUI
extension CGImage {
// width is for total, ratio is second stripe relative to full width
static func stripes(colors: (UIColor, UIColor), width: CGFloat, ratio: CGFloat) -> CGImage {
let filter = CIFilter.stripesGenerator()
filter.color0 = CIColor(color: colors.0)
filter.color1 = CIColor(color: colors.1)
filter.width = Float(width-width*ratio)
filter.center = CGPoint(x: width, y: 0)
let size = CGSize(width: width+width*ratio, height: 1)
let bounds = CGRect(origin: .zero, size: size)
// keep a reference to a CIContext if calling this often
return CIContext().createCGImage(filter.outputImage!.clamped(to: bounds), from: bounds)!
}
}
然后使用ImagePaint
Circle().fill(
ImagePaint(image: Image(decorative: CGImage.stripes(colors: (.blue, .yellow), width: 80, ratio: 0.25), scale: 1))
)
.rotationEffect(.degrees(-30))
或
CILineScreen
过滤器可能更符合您的要求。我不确定您想要什么,但另一种可能的解决方案是在ZStack线性渐变和阴影中使用不同的背景,以产生凸凹效果。因此,它有助于您的背景有一点颜色,而不是白色。一些样本:
守则:
struct ContentView: View {
var body: some View {
ZStack {
Color.yellow.opacity(0.1)
VStack(spacing: 50) {
myCircle()
myCircle1()
}
}
}
}
struct myCircle: View {
var body: some View {
Circle().foregroundColor(Color.clear)
.frame(width: 100, height: 100)
.background(
ZStack {
LinearGradient(gradient: Gradient(colors: [Color( #colorLiteral(red: 0.9764705896, green: 0.850980401, blue: 0.5490196347, alpha: 1) ), Color(#colorLiteral(red: 1, green: 1, blue: 1, alpha: 1))]), startPoint: .topLeading, endPoint: .bottomTrailing)
Circle()
.stroke(Color.clear, lineWidth: 10)
.shadow(color: Color(#colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)), radius: 3, x: -5, y: -5)
Circle()
.stroke(Color.clear, lineWidth: 10)
.shadow(color: Color(#colorLiteral(red: 0.9764705896, green: 0.850980401, blue: 0.5490196347, alpha: 1)), radius: 3, x: 3, y: 3)
}
)
.clipShape(Circle())
.shadow(color: Color( #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1) ), radius: 20, x: -20, y: -20)
.shadow(color: Color( #colorLiteral(red: 0.9764705896, green: 0.850980401, blue: 0.5490196347, alpha: 1) ), radius: 20, x: 20, y: 20)
}
}
struct myCircle1: View {
var body: some View {
Circle().foregroundColor(Color.clear)
.frame(width: 100, height: 100)
.background(
ZStack {
LinearGradient(gradient: Gradient(colors: [Color( #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1) ), Color(#colorLiteral(red: 0.9764705896, green: 0.850980401, blue: 0.5490196347, alpha: 1))]), startPoint: .topLeading, endPoint: .bottomTrailing)
Circle()
.stroke(Color.clear, lineWidth: 10)
.shadow(color: Color(#colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)), radius: 3, x: -5, y: -5)
Circle()
.stroke(Color.clear, lineWidth: 10)
.shadow(color: Color(#colorLiteral(red: 0.9764705896, green: 0.850980401, blue: 0.5490196347, alpha: 1)), radius: 3, x: 3, y: 3)
}
)
.clipShape(Circle())
.shadow(color: Color( #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1) ), radius: 20, x: -20, y: -20)
.shadow(color: Color( #colorLiteral(red: 0.9764705896, green: 0.850980401, blue: 0.5490196347, alpha: 1) ), radius: 20, x: 20, y: 20)
}
}
谢谢你的条纹图案。稍微调整了一下,以便可以旋转任何形状的图案填充
import SwiftUI
import CoreImage.CIFilterBuiltins
extension CGImage {
static func generateStripePattern(
colors: (UIColor, UIColor) = (.clear, .black),
width: CGFloat = 6,
ratio: CGFloat = 1) -> CGImage? {
let context = CIContext()
let stripes = CIFilter.stripesGenerator()
stripes.color0 = CIColor(color: colors.0)
stripes.color1 = CIColor(color: colors.1)
stripes.width = Float(width)
stripes.center = CGPoint(x: 1-width*ratio, y: 0)
let size = CGSize(width: width, height: 1)
guard
let stripesImage = stripes.outputImage,
let image = context.createCGImage(stripesImage, from: CGRect(origin: .zero, size: size))
else { return nil }
return image
}
}
extension Shape {
func stripes(angle: Double = 45) -> AnyView {
guard
let stripePattern = CGImage.generateStripePattern()
else { return AnyView(self)}
return AnyView(Rectangle().fill(ImagePaint(
image: Image(decorative: stripePattern, scale: 1.0)))
.scaleEffect(2)
.rotationEffect(.degrees(angle))
.clipShape(self))
}
}
用法
struct ContentView: View {
var body: some View {
VStack {
Rectangle()
.stripes(angle: 30)
Circle().stripes()
Capsule().stripes(angle: 90)
}
}
}
它适用于圆形,但当您需要将图案填充旋转为其他形状时,结果是“是”,它只生成垂直条纹。因此,如果要将最终结果旋转到任意角度,它实际上只适用于圆。要使其适用于任何形状,您可以在图像创建阶段应用旋转变换。谢谢。根据您的回答添加了旋转,我希望我正确地理解了您)请查看我的回答有一点让我头疼(看起来它在@flyer2001的解决方案中是固定的),那就是旋转传递到ImagePaint中的图像并不像您想象的那样工作。它看起来像是在引擎盖下弹出了一个
SwiftUI.ModifiedContent
视图,而不是一个新的SwiftUI.Image。如果您需要最终结果是一个图像而不是一个视图,请调整函数以对CIImage应用旋转或任何变换,然后将CGImage边界设置为您想要的最终图像的大小。然后从该CGImage初始化SwiftUI映像。