You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI CheckMarkView问题:布局错位与勾选标记动画收尾卡顿求助

Solution to CheckMarkView Alignment and Animation Issues

Fix 1: Alignment When Adding Parent Frame

The misalignment happens because the original ZStack wasn’t set to fill its parent frame and keep content centered. By making the ZStack expand to the parent’s size, adding a frame to CheckMarkView won’t break the positioning of the circle and arrow.

Fix 2: Checkmark Position & Smooth Animation

  • The hardcoded offset(x:150, y:420) pushed the checkmark way outside the circle. We’ll replace this with relative path coordinates that sit centered inside the circle’s bounds.
  • Adjusted the path points to fit within the 128x128 circle, and matched the checkmark’s frame to the circle’s size.
  • Tweaked the spring animation parameters for a more natural, smooth finish.

Corrected Code

struct CheckMarkView: View {
    @State private var borderInit = false
    @State private var spinArrow = false
    @State private var dismissArrow = false
    @State private var displayCheckmark = false
    
    var body: some View {
        ZStack(alignment: .center) {
            // Circle border animation
            Circle()
                .strokeBorder(style: StrokeStyle(lineWidth: borderInit ? 10 : 64))
                .frame(width: 128, height: 128)
                .foregroundColor(borderInit ? .white : .black)
                .animation(.easeOut(duration: 3).speed(1.5), value: borderInit)
            
            // Spinning arrow icon
            Image(systemName: "arrow.2.circlepath")
                .font(.system(size: 40))
                .foregroundColor(.white)
                .rotationEffect(.degrees(spinArrow ? 360 : -360))
                .opacity(dismissArrow ? 0 : 1)
                .animation(.easeOut(duration: 2), value: spinArrow)
                .animation(.easeInOut(duration: 1).delay(1), value: dismissArrow)
            
            // Centered checkmark
            Path { path in
                // Relative points centered in 128x128 frame
                path.move(to: CGPoint(x: 32, y: 64))
                path.addLine(to: CGPoint(x: 56, y: 88))
                path.addLine(to: CGPoint(x: 96, y: 40))
            }
            .trim(from: 0, to: displayCheckmark ? 1 : 0)
            .stroke(style: StrokeStyle(lineWidth: 10, lineCap: .round, lineJoin: .round))
            .foregroundColor(.white)
            .frame(width: 128, height: 128) // Match circle size
            .animation(Animation.interpolatingSpring(stiffness: 120, damping: 15, initialVelocity: 0).delay(2), value: displayCheckmark)
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity) // Fill parent frame
        .background(.black)
        .onAppear {
            // Trigger all animations in sequence
            borderInit.toggle()
            spinArrow.toggle()
            DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
                dismissArrow.toggle()
            }
            DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
                displayCheckmark.toggle()
            }
        }
    }
}

Key Improvements

  • Alignment: The ZStack fills its parent, so any frame added to CheckMarkView keeps all elements centered.
  • Checkmark Placement: The path uses relative coordinates within a matching 128x128 frame, ensuring it stays inside the circle.
  • Animation Smoothness: Explicit animations (using value:) prevent unexpected behavior, and adjusted spring parameters create a more natural checkmark reveal.

内容的提问来源于stack exchange,提问作者iosdev1111

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 18:34:58