繁体   English   中英

如何为 SwiftUI 弧添加阴影?

[英]How to add shadow to SwiftUI arc?

我有以下弧线:

struct Arc : Shape
{
    @Binding var endAngle: Double
    var center: CGPoint
    var radius: CGFloat
    func path(in rect: CGRect) -> Path
    {
        var path = Path()

        path.addArc(center: center, radius: radius, startAngle: .degrees(270), endAngle: .degrees(endAngle), clockwise: false)

        return path.strokedPath(.init(lineWidth: 50, lineCap: .round))
    }
}

如何添加阴影,类似于 Apple Watch 上的活动弧线,以便在整个圆圈处 endAngle 仍然可辨别?

编辑:在 360+ 度(如此完整的圆)处还有一个额外的问题,即两个弧端合并并显示为径向线(我看到这一点是因为我应用了AngularGradient )。 当然Arc不会像 Apple Watch arcs 那样做高级的事情,比如在startAngle position 之上继续。 但这正是我想要的。 有谁知道如何在 SwiftUI 中做到这一点?

在此处输入图像描述 那这个呢? 好吧...有点“棘手”

import SwiftUI

    struct Arc : Shape
    {
    @Binding var startAngle: Double
    @Binding var endAngle: Double

    var center: CGPoint
    var radius: CGFloat
    var color: Color

    func path(in rect: CGRect) -> Path
    {
        var path = Path()

        let cgPath = CGMutablePath()
        cgPath.addArc(center: CGPoint(x: rect.midX, y: rect.midY), radius: radius, startAngle: CGFloat(startAngle), endAngle: CGFloat(endAngle), clockwise: true)

      //  path.addArc(center: center, radius: radius, startAngle: .degrees(270), endAngle: .degrees(endAngle), clockwise: false)

        path = Path(cgPath)

        return path.strokedPath(.init(lineWidth: 50, lineCap: .round))
    }
}

struct ContentView: View {
    var body: some View {
        ZStack() {
       //     Arc(endAngle: .constant(269), center: CGPoint(x: 200, y: 200), radius: 150, color: .red).foregroundColor(.red).opacity(0.2)
            Arc(startAngle: .constant(80 + 271), endAngle: .constant(80 + 271 + 340), center: CGPoint(x: 205, y: 205), radius: 150, color: .red).foregroundColor(.red)//.shadow(color: .black, radius: 5, x: -30, y: -170)
            Arc(startAngle: .constant(90), endAngle: .constant(80 + 270), center: CGPoint(x: 200, y: 200), radius: 150, color: .red).foregroundColor(.red).shadow(color: .black, radius: 5, x: -114, y: -230)
        }.background(Color.black)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

你的意思是这样的吗?

struct Arc : Shape
{
    @Binding var endAngle: Double

    var center: CGPoint
    var radius: CGFloat
    var color: Color

    func path(in rect: CGRect) -> Path
    {
        var path = Path()

        path.addArc(center: center, radius: radius, startAngle: .degrees(270), endAngle: .degrees(endAngle), clockwise: false)

        return path.strokedPath(.init(lineWidth: 50, lineCap: .round))
    }
}

struct ContentView: View {
    var body: some View {
        ZStack() {
            Arc(endAngle: .constant(269), center: CGPoint(x: 200, y: 200), radius: 150, color: .red).foregroundColor(.red).opacity(0.2)
            Arc(endAngle: .constant(90), center: CGPoint(x: 200, y: 200), radius: 150, color: .red).foregroundColor(.red)
        }
    }
}

嗨,您可以通过在项目文件中编写扩展来修复和处理所有这些功能

    import UIKit
extension UIView {
func roundCorners(corners: UIRectCorner, radius: CGFloat) {
    let path = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
    let mask = CAShapeLayer()
    mask.path = path.cgPath
    self.layer.mask = mask
}

// MARK: Shadow extension UIView {

func dropShadow(scale: Bool = true) {
    layer.masksToBounds = false
    layer.shadowColor = UIColor.blue.cgColor
    layer.shadowOpacity = 1.0
    layer.shadowOffset = CGSize(width: -1.5, height: 3)
    layer.shadowRadius = 3

    layer.shadowPath = UIBezierPath(rect: bounds).cgPath
    layer.shouldRasterize = true
    layer.rasterizationScale = scale ? UIScreen.main.scale : 1
}

func dropShadow(color: UIColor, opacity: Float = 0.5, offSet: CGSize, radius: CGFloat = 1, scale: Bool = true) {
    layer.masksToBounds = false
    layer.shadowColor = color.cgColor
    layer.shadowOpacity = opacity
    layer.shadowOffset = offSet
    layer.shadowRadius = radius

    layer.shadowPath = UIBezierPath(rect: self.bounds).cgPath
    layer.shouldRasterize = true
    layer.rasterizationScale = scale ? UIScreen.main.scale : 1
}

func setAnchorPoint(_ point: CGPoint) {
    var newPoint = CGPoint(x: bounds.size.width * point.x, y: bounds.size.height * point.y)
    var oldPoint = CGPoint(x: bounds.size.width * layer.anchorPoint.x, y: bounds.size.height * layer.anchorPoint.y)

    newPoint = newPoint.applying(transform)
    oldPoint = oldPoint.applying(transform)

    var position = layer.position

    position.x -= oldPoint.x
    position.x += newPoint.x

    position.y -= oldPoint.y
    position.y += newPoint.y

    layer.position = position
    layer.anchorPoint = point
}

class func fromNib<T: UIView>() -> T {
    guard let view = Bundle.main.loadNibNamed(String(describing: T.self), owner: nil, options: nil)?.first as? T else { fatalError() }
    return view
}

现在在 storyboard 中,您可以处理阴影或不想处理阴影,而且太多了,您可以使用唯一需要的部分。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM