如何使用SwiftUI复现该Objective-C实现的视图滑入动画效果?
Absolutely! You can totally recreate that exact right-to-left push transition from your old Objective-C app in SwiftUI—let me break this down for you.
First, Let's Recap Your Original Code
Your Objective-C CATransition was setting up:
- A push transition (new view pushes the old one out of the way)
- Direction: sliding in from the right (
kCATransitionFromRight) - Duration: 0.5 seconds
- Easing curve:
easeInEaseOutfor smooth start/end
SwiftUI Implementation Options
Here are two straightforward ways to match this behavior, depending on how you're updating your view:
1. Quick Built-in Transition (SwiftUI 3.0+)
If you're toggling or replacing a view (using a @State or @Binding variable to switch content), SwiftUI has a built-in transition that perfectly matches your old code:
import SwiftUI struct ContentView: View { @State private var showUpdatedPhase = false var body: some View { VStack(spacing: 20) { Button("Update View") { // Apply the exact timing from your original code withAnimation(.easeInOut(duration: 0.5)) { showUpdatedPhase.toggle() } } // Swap views with the push transition if showUpdatedPhase { UpdatedPhaseCell() .transition(.push(from: .trailing)) // This is the key! } else { OriginalPhaseCell() .transition(.push(from: .trailing)) } } .padding() } } // Placeholder views matching your original "phaseCell" struct OriginalPhaseCell: View { var body: some View { RoundedRectangle(cornerRadius: 8) .fill(.blue) .frame(height: 150) .overlay(Text("Original Phase").foregroundColor(.white)) } } struct UpdatedPhaseCell: View { var body: some View { RoundedRectangle(cornerRadius: 8) .fill(.green) .frame(height: 150) .overlay(Text("Updated Phase (From Right)").foregroundColor(.white)) } }
The .push(from: .trailing) transition directly mirrors the kCATransitionPush + kCATransitionFromRight behavior, and the withAnimation block applies the 0.5s ease-in-out timing exactly like your original code.
2. Custom Transition for Fine-Grained Control
If you want even more control (to match every detail of the original CATransition), you can create a custom asymmetric transition:
extension AnyTransition { static func pushFromRight() -> AnyTransition { // Define how the new view enters, and old view exits let insertion = AnyTransition.move(edge: .trailing) .combined(with: .opacity) let removal = AnyTransition.move(edge: .leading) .combined(with: .opacity) return .asymmetric(insertion: insertion, removal: removal) } }
Use it just like the built-in version, and even specify the exact CAMediaTimingFunction if needed:
withAnimation(Animation.timingFunction(CAMediaTimingFunction(name: .easeInEaseOut), duration: 0.5)) { showUpdatedPhase.toggle() } // In your view hierarchy UpdatedPhaseCell() .transition(.pushFromRight())
Quick Notes
- If you're updating content within a single view (not swapping entire views), wrap the dynamic content change in
withAnimationand apply the transition modifier to the changing part. - The built-in
.pushtransition works on iOS 15+, macOS 12+, which should be widely supported for most modern apps.
内容的提问来源于stack exchange,提问作者Sundraw

