我正在试着画一个相当基本的鸟的形状.我用圆圈画身体,我试着画上喙(以红色突出显示),如下面的参考图片所示.

图片参考:

enter image description here

struct Beak: Shape {
    func path(in rect: CGRect) -> Path {
        var path = Path()
        path.move(to: CGPoint(x: rect.width/4, y: rect.height/2))
        path.addLine(to: CGPoint(x: 0, y: rect.height/2))
        // draw a line back to the circumference at a given angle
        // & close it with an arc along the circumference of the Body circle
        path.addLine(to: ??) 
        return path
    }
}

struct BirdView: View {
    var body: some View {
        ZStack {
            // MARK: Body
            Circle()
                .stroke(lineWidth: 10)
                .frame(width: 150)
                .overlay(alignment: .center) {
                    Circle()
                        .fill(.yellow)
                }
            
            // MARK: Beak
            Beak()
                .stroke(lineWidth: 5)
            
        }
        .frame(width: 300, height: 300)
        .background(.orange)
    }
}

我想要实现的是让喙也沿着身体圆周用一条弧线闭合,这样我就可以在以后通过旋转来模拟喙的打开/闭合.如有任何帮助,我们不胜感激.

推荐答案

如果你用.addArc来画曲线,那就没什么大不了的.如果使用中点作为圆弧的起点,然后使用.offset将最终形状移动到适当的位置,可能会更容易.这也为以后添加旋转效果铺平了道路.

要将鸟头的特征保持在一起,可以将它们全部作为覆盖应用到基圆,也可以在单独的ZStack个圆圈中构建它们.在单独的ZStack只中做这件事可能更简单,这ZStack的帧大小可以用来确定圆圈的大小以及眼睛和喙的大小.

以下是改编后的Shape强:

struct Beak: Shape {
    let angleDegrees: CGFloat
    func path(in rect: CGRect) -> Path {
        var path = Path()
        path.move(to: CGPoint(x: rect.midX, y: rect.midY))
        path.addArc(
            center: CGPoint(x: rect.maxX, y: rect.midY),
            radius: rect.midX,
            startAngle: .degrees(180),
            endAngle: .degrees(180 + angleDegrees),
            clockwise: angleDegrees < 0
        )
        path.addLine(to: CGPoint(x: 0, y: rect.midY))
        path.closeSubpath()
        return path
    }
}

以下是你可以使用它的方法.我忍不住要把它制作成动画😄

struct BirdView: View {
    @State private var gapeAngle = Angle.zero

    private func birdHead(diameter: CGFloat) -> some View {
        ZStack {
            Circle()
                .fill(.yellow)

            Circle()
                .stroke(lineWidth: 5)

            // Eye
            Ellipse()
                .fill(.black)
                .frame(width: diameter / 5, height: diameter / 5.55)
                .offset(x: -diameter / 4.7, y: -diameter / 5.35)

            // Upper beak
            Beak(angleDegrees: 20)
                .stroke(style: .init(lineWidth: 5, lineJoin: .round))
                .foregroundStyle(.red)
                .offset(x: -diameter / 2)
                .rotationEffect(gapeAngle)

            // Lower beak
            Beak(angleDegrees: -20)
                .stroke(style: .init(lineWidth: 5, lineJoin: .round))
                .foregroundStyle(.red)
                .offset(x: -diameter / 2)
                .rotationEffect(-gapeAngle)
        }
        .frame(width: diameter, height: diameter)
    }

    var body: some View {
        birdHead(diameter: 150)
            .padding(.leading, 50)
            .frame(width: 300, height: 300)
            .background(.orange)
            .onAppear {
                withAnimation(.easeInOut.repeatForever(autoreverses: true)) {
                    gapeAngle = .degrees(5)
                }
            }
    }
}

Animation

Ios相关问答推荐

以编程方式更改VC&39;S导航栏按钮的属性,以响应另一个VC中的按钮按下

如何在SwiftUI中基于嵌套视图中的状态动态显示外部视图的内容?

如何在 Swift 中存储具有关联值的协议?

如何在用户点击的位置使用SceneKit渲染球体?

_SKStoreProductParameterAdNetworkSourceIdentifier未定义符号

使用 SwiftUI 显示多个 VNRecognizedObjectObservation 边界框时偏移量错误

使用 SceneKit 从 CapturedRoom.walls 重新创建 RoomPlan

在 Swift 中映射 MySQL 数据

在 SwiftUI 中打开 PDF

Swift 5.7 - 使存在的任何协议符合 Hashable

XCode 14 Beta 中 NavigationStack 的正文渲染问题

如何在不支持并发的自动关闭中修复'async'调用?

如何在 SwiftUI 中检测 TextField 的实时变化?

SwiftUI 视图 - viewDidLoad()?

无法验证客户端 3000

在 Swift 中上传带参数的图像

在 iOS 7 上更改标签栏色调 colored颜色

快速从 NSTimeInterval 转换为小时、分钟、秒、毫秒

iOS 中的 Google Analytics SDK 3.0 _sqlite3 链接器错误

在两个或多个 iPhone 应用程序之间共享数据