如何只绘制圆周的顶部?

问题描述 投票:0回答:1

我正在尝试在 SwiftUI 中绘制弧线,正在练习,我想从苹果网站制作此视图(如图所示),其中展示了如何实现动态岛现场活动。

This is the view im trying to replicate

我尝试过使用路径,但我不确定如何只绘制圆弧而不是像我的代码那样绘制半圆。

这是使用

Path
的代码:

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

        let center = CGPoint(x: rect.midX, y: rect.midY)
        let radius: CGFloat = 100
        let startAngle = Angle(degrees: 180)
        let endAngle = Angle(degrees: 0) 
        path.addArc(center: center, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: false)
        
        return path
    }
}

这是一种更接近的方法,使用

Circle
并修剪它,但我不知道如何“捣碎它”并使其更平坦,并且还圆角,我尝试过使用
.cornerRadius
并制作
 frame
宽且不高,但我没有看到任何结果,只有圆圈调整为较小的尺寸
frame

Circle()
   .trim(from: 0.55, to: 0.95)
   .stroke(.linearGradient(colors: [.blue, .cyan],
                          startPoint: .leading,
                          endPoint: .trailing), lineWidth: 5)
ios swift swiftui dynamic dynamic-island
1个回答
0
投票

路径使用的角度从右侧零开始(罗盘方向的东方)并随着顺时针方向增加。

您创建了一条从 180 度(正西)开始,到 0 度(正东)逆时针绘制的弧。画了一个半圆。

如果您想绘制更少的圆,请在起始角度添加一些偏移,并从结束角度减去相同的量。因此,正如 Paulw11 建议的那样,尝试 180+40 = 220 度作为弧线的左侧(西侧),0-40 = -40 或 360-40 = 320 度作为弧线的右侧结束。

此代码:

struct ArcShape: Shape {
    var radius: CGFloat // The circle radius to use. Bigger numbers make a flatter but bigger arc
    var arcOffset: CGFloat // The number of degrees above the center to start the left and right of the arc.
    
  func path(in rect: CGRect) -> Path {
      var path = Path()
      let center = CGPoint(x: rect.midX, y: rect.midY)
      let startAngle = Angle(degrees: 180 + arcOffset)
      let endAngle = Angle(degrees: 0 - arcOffset)
      path.addArc(center: center, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: false)
      
      return path
  }
}

struct ContentView: View {
    var body: some View {
        // GeometryReader lets us learn things like the size of the screen
        GeometryReader { proxy in
            VStack(alignment: .center) {
                Spacer()
                    .frame(height: 100)
                let inset: CGFloat = 10
                let frameSize = proxy.size.width - inset * 2
                // Draw 2 arcs on top of each other.
                ZStack {
                    // The first blue arc will be from
                    // 180-30 = 210° to
                    // 360-30 = 330°
                    ArcShape(radius: frameSize / 2 - 20, arcOffset: 30)
                        .stroke(style: StrokeStyle(lineWidth: 20, lineCap: .round))
                        .foregroundColor(Color(red: 0.2, green: 0.2, blue: 0.7))
                        .frame(width: frameSize, height: frameSize)
                    // The second cyan arc will be from
                    // 180-70 = 110° to
                    // 360-70 = 190°
                    ArcShape(radius: frameSize / 2 - 20, arcOffset: 70)
                        .stroke(style: StrokeStyle(lineWidth: 20, lineCap: .round))
                        .foregroundColor(.cyan)
                        .frame(width: frameSize, height: frameSize)
                }
                .border(Color.green, width: 1) //Remove if you don't want a border
                .padding(.leading, inset)

            }
        }
    }
}

#Preview {
    ContentView()
}

产生如下所示的图像:

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.