Как добавить тень в дугу SwiftUI? - PullRequest
1 голос
/ 09 ноября 2019

У меня есть следующая дуга:

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 не будет продвигать такие вещи, как продолжение выше позиции startAngle, как это делают дуги Apple Watch. Но это было то, что я искал. Кто-нибудь знает, как это сделать в SwiftUI?

Ответы [ 3 ]

1 голос
/ 09 ноября 2019

ты имеешь в виду что-то подобное?

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)
        }
    }
}
1 голос
/ 09 ноября 2019

enter image description here что по этому поводу? хорошо ... немного "сложно"

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()
    }
}
0 голосов
/ 09 ноября 2019

Привет, вы можете исправить и обработать все эти функции, написав расширение в файле вашего проекта.

    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
}

Теперь в раскадровке вы можете обрабатывать тени или не хотите, и это слишком много,Вы можете использовать только ту часть, которая вам нужна.

...