1、简单实现缩放动画
import SwiftUI
struct ContentView : View
{
@State var factor: CGFloat = 1
var body: some View
{
VStack
{
Image("couples")
.scaleEffect(factor)
.animation(.default)
Divider().fixedSize()
Button(action:
{
self.factor += 0.2
}) {
Text("Zoom in")
}
}
}
}
2、withAnimation实现缩放和渐隐动画
import SwiftUI
struct ContentView : View
{
@State var factor: Double = 1
@State var alpha: Double = 1
var body: some View
{
Image("couples")
.scaleEffect(CGFloat(factor))
.opacity(alpha)
.onTapGesture
{
withAnimation(.linear(duration: 1.0))
{
self.factor += 0.1
self.alpha -= 0.2
}
}
}
}
3、渐缓时间曲线进行位移动画 -- easeOut
import SwiftUI
struct ContentView : View
{
@State var distance: Double = 0
var body: some View
{
VStack
{
Image("couples")
.offset(x: 0, y: CGFloat(distance))
.animation(.easeOut(duration: 2))
Divider().fixedSize()
Button(action:
{
self.distance -= 120
}) {
Text("Move Effect")
}
}
}
}
4、旋转动画 -- rotationEffect
//
// ContentView.swift
// Copyright © www.hdjc8.com
//
import SwiftUI
struct ContentView : View
{
@State var angle: Double = 0
var body: some View
{
VStack
{
Image("couples")
.rotationEffect(Angle.init(degrees: angle))
.animation(.spring())
Divider().fixedSize()
Button(action:
{
self.angle += 90
}) {
Text("Rotation Effect")
}
}
}
}
5、色相和亮度复合动画 -- hueRotation & brightness
import SwiftUI
struct ContentView : View
{
@State var angle: Double = 0
@State var brightness: Double = 0
var body: some View
{
VStack
{
Image("couples")
.hueRotation(Angle.init(degrees: angle))
.brightness(brightness)
.animation(.linear(duration: 2))
Divider().fixedSize()
Button(action:
{
self.angle = 180
self.brightness = 2
}) {
Text("Move Effect")
}
}
}
}
6、动画的播放速度和延迟时间 -- speed & delay
import SwiftUI
struct ContentView : View
{
@State var factor: Double = 1.0
var animation: Animation
{
Animation.linear(duration: 1)
// .speed(5)
.delay(1)
}
var body: some View
{
VStack
{
Image("couples")
.scaleEffect(CGFloat(factor))
.animation(animation)
Divider().fixedSize()
Button(action:
{
self.factor = 0.1
}) {
Text("Zoom In Effect")
}
}
}
}
7、循环动画实现和循环次数设置 -- repeatForever & repeatCount
autoreverses: 循环动画默认是有自动反转的特性,当动画结束时会播放动画开始时的状态。
import SwiftUI
struct ContentView : View
{
@State var angle: Double = 0
var animation: Animation
{
Animation.spring()
// .repeatForever(autoreverses: false)
.repeatCount(3)
}
var body: some View
{
VStack
{
Image("couples")
.rotationEffect(Angle.init(degrees: angle))
.animation(animation)
Divider().fixedSize()
Button(action:
{
self.angle = 45
}) {
Text("Repeat Forever Effect")
}
}
}
}
8、动画的方式显示或隐藏指定位图
import SwiftUI
struct ContentView : View
{
@State private var showingPassword = false
@State private var password = ""
var body: some View
{
VStack
{
Toggle(isOn: $showingPassword.animation(
.linear(duration: 1)))
{
Text("Toggle Password")
}
if showingPassword
{
TextField("Password", text: $password)
.padding()
.border(Color.green, width: 2)
}
}
.padding()
}
}
9、过渡动画
import SwiftUI
struct ContentView : View
{
@State var showPicture = false
var body: some View
{
VStack
{
Button(action:
{
withAnimation
{
self.showPicture.toggle()
}
}) {
Text("Show picture")
}
if showPicture
{
// Image("logo")
// Image("logo")
// .transition(.move(edge: .top))
// Image("logo")
// .transition(.scale(scale: 0))
// Image("logo")
// .transition(.slide)
// Image("logo")
// .transition(.asymmetric(insertion: .scale(scale: 0), removal: .slide))
Image("logo")
.transition(AnyTransition.scale(scale: 0).combined(with:.slide))
}
}
}
}
10、模拟手机解锁色彩变换动画 -- hueRotation
import SwiftUI
struct ContentView : View
{
@State private var hueShift: Bool = false
var body: some View
{
ZStack
{
Text("Slide to unlock")
.font(.largeTitle)
.foregroundColor(.purple)
.brightness(-0.2)
.hueRotation(.degrees(hueShift ? 0 : 720))
.animation(Animation.easeInOut(duration: 4))
.onTapGesture
{
self.hueShift = true
}
Rectangle()
.frame(maxWidth: 220, maxHeight: 40)
.foregroundColor(.white)
.opacity(0.5)
.rotationEffect(.degrees(0), anchor: .trailing)
.scaleEffect(x:hueShift ? 0 : 1, y:1, anchor: .trailing)
.animation(Animation.easeInOut(duration: 4))
}
}
}
11、三维旋转、缩放和偏移复合动画 -- rotation3DEffect
import SwiftUI
struct ContentView : View
{
@State var angle: Double = 0
@State var scale: Double = 0
@State var offsetY: Double = -200
var body: some View
{
VStack
{
Image("bitcoin")
.offset(x: 0, y: CGFloat(offsetY))
.scaleEffect(CGFloat(scale))
.rotation3DEffect(.degrees(angle), axis: (x: 0, y: 1, z: 0))
.animation(.interpolatingSpring(stiffness: 100, damping: 10))
Divider().fixedSize()
Button(action:
{
if(self.angle == 0)
{
self.offsetY = 0
self.scale = 1
self.angle = 360*10
}
else
{
self.offsetY = -200
self.scale = 0
self.angle = 0
}
}) {
Text("Rotation Effect")
}
}
}
}
12、色轮旋转动画
import SwiftUI
struct ContentView : View
{
@State var shouldRotate = false
var body: some View
{
ZStack
{
Circle()
.stroke(style: .init(lineWidth: 50))
.fill(AngularGradient(
gradient: Gradient(colors: [.red, .orange, .yellow, .blue, .green, .purple, .red]),
center: .center))
.padding(40)
.rotationEffect(.degrees(shouldRotate ? 720 : 0))
.animation(.easeInOut(duration: 4))
Button(action:
{
self.shouldRotate.toggle()
}) {
Text("Rock and roll")
}
}
}
}
13、聚焦动画
import SwiftUI
struct ContentView : View
{
@State var isAnimating: Bool = false
var body: some View
{
VStack
{
Image("Picture")
.clipShape(
Circle()
.inset(by: isAnimating ? 120 : 0)
.offset(x: isAnimating ? 30 : 0, y: isAnimating ? -100 : 0)
)
.animation(.easeOut(duration: 2))
Divider().fixedSize()
Button(action:
{
self.isAnimating.toggle()
}) {
Text("Start animation")
}
}
}
}
14、探照灯滚动扫描动画
import SwiftUI
struct ContentView : View
{
@State var isAnimating: Bool = false
var body: some View
{
ZStack
{
Image("Picture")
.blur(radius: 6)
.brightness(0.4)
Image("Picture")
.clipShape(
Rectangle()
.size(CGSize(width: 340, height: 100))
.offset(x: 0, y: isAnimating ? 590 : -100)
)
.animation(.linear(duration: 2))
.onTapGesture
{
self.isAnimating.toggle()
}
}
}
}
15、花朵旋转动画
import SwiftUI
struct ContentView : View {
@State private var shouldRotate: Bool = false
@State private var shouldScale: Bool = false
var body: some View {
FlowerCapsule()
.scaleEffect(shouldScale ? 0.2 : 1)
.rotationEffect(.degrees(shouldRotate ? 0 : 360), anchor: .center)
.animation(.easeInOut(duration: 4))
.onTapGesture
{
self.shouldRotate.toggle()
self.shouldScale.toggle()
}
}
}
struct NewCapsule: View
{
var color : Color
var degree : Double
var body: some View
{
Capsule()
.foregroundColor(color)
.frame(width : 60, height: 90)
.offset(x: 0, y: 60)
.opacity(0.75)
.rotationEffect(.degrees(degree))
}
}
struct FlowerCapsule: View
{
var body: some View
{
ZStack
{
NewCapsule(color: .red, degree: 0)
NewCapsule(color: .red, degree: 45)
NewCapsule(color: .yellow, degree: 90)
NewCapsule(color: .yellow, degree: 135)
NewCapsule(color: .blue, degree: 180)
NewCapsule(color: .blue, degree: 225)
NewCapsule(color: .green, degree: 270)
NewCapsule(color: .green, degree: 315)
}
}
}
16、序列动画
序列动画:指一个动画结束时执行另一段动画
import SwiftUI
struct ContentView: View
{
@State var offsetX: CGFloat = 0
let colors : [Color] = [.red, .orange, .yellow, .green, .blue]
let animations : [Animation] =
[Animation.interpolatingSpring(stiffness: 100, damping: 10),
Animation.interpolatingSpring(stiffness: 100, damping: 10).delay(0.3),
Animation.interpolatingSpring(stiffness: 100, damping: 10).delay(0.6),
Animation.interpolatingSpring(stiffness: 100, damping: 10).delay(0.9),
Animation.interpolatingSpring(stiffness: 100, damping: 10).delay(1.2)]
var body: some View
{
VStack
{
List(0..<5)
{ item in
Rectangle()
.fill(self.colors[item])
.frame(width:50, height:50)
.offset(x: self.offsetX, y: 0)
.animation(self.animations[item])
}
Button(action: {
self.offsetX += 200
}) {
Text("Start animation")
}
}
}
}
17、履带滚动动画 -- dashPhase相位移动
import SwiftUI
struct ContentView : View
{
@State private var isAnimating = false
var body: some View
{
ZStack
{
Capsule()
.stroke(Color.orange, style: StrokeStyle(lineWidth: 10,
lineCap: .butt, lineJoin: .bevel,
miterLimit: 10, dash: [20,11],
dashPhase: isAnimating ? 200 : 0))
.frame(width : 300, height:100)
.animation(.easeInOut(duration: 3))
Button(action: {
self.isAnimating.toggle()
}) {
Text("Rock and roll")
}
}
}
}
18、VideoPlayer播放视频素材
import SwiftUI
import AVKit
struct ContentView : View
{
var body: some View
{
VideoPlayer(player: AVPlayer(url:
URL(fileURLWithPath: Bundle.main.path(forResource: "movie", ofType: "mp4")!) as URL))
{
Text("Watermark of video")
}
.padding()
.background(Color.black)
.ignoresSafeArea()
}
}
19、实现过渡动画 -- matchedGeometryEffect
import SwiftUI
import AVKit
struct ContentView: View
{
@Namespace private var animation
@State private var isZoom = false
var body: some View
{
VStack(alignment: .leading, spacing:10)
{
if isZoom
{
VideoPlayer(player: AVPlayer(url: URL(fileURLWithPath: Bundle.main.path(forResource: "movie", ofType: "mp4")!) as URL))
.frame(height:300)
.matchedGeometryEffect(id: "VideoPlayer", in: animation)
Text("Colorful waterfall")
.font(.title)
.padding(.leading, 10)
.matchedGeometryEffect(id: "VideoTitle", in: animation)
.onTapGesture
{
withAnimation(.easeOut(duration: 0.3))
{
self.isZoom.toggle()
}
}
Text("The colorful waterfall is located in the green forest not far from the Zizi Cliff. It plunges from the high granite and flows along the red rock of the scales. \n\nThe layers of water are sprinkled like feathers, reflecting the red rock. \n\nA flowing white silk soft satin is lining the red material, and the color is very rich. \n\nIf you encounter sunlight, you can see the rainbow appear in the mist, making people forget to return.")
.padding(.leading, 10)
.foregroundColor(.gray)
.matchedGeometryEffect(id: "VideoReview", in: animation)
Spacer()
}
else
{
Spacer()
Text("""
Review of Diamond Waterfalls
Reviewed March 13, 2021\n
Buried in Diamond Botanical Park, Diamond Falls displays the minerals of the upstream sulfur hot springs. The various minerals stain the rock leaving behind reds, ochers, and other earth tones of color. Obviously some visitors did not appreciate it but we found it very interesting and quite photogenic.\n
Date of experience: January 2021\n
""")
.padding(.leading, 10)
.font(.title2)
.foregroundColor(.purple)
.matchedGeometryEffect(id: "VideoReview", in: animation)
HStack
{
VideoPlayer(player: AVPlayer(url: URL(fileURLWithPath: Bundle.main.path(forResource: "movie", ofType: "mp4")!) as URL))
.frame(width:80, height:50)
.matchedGeometryEffect(id: "VideoPlayer", in: animation)
Text("Colorful waterfall")
.matchedGeometryEffect(id: "VideoTitle", in: animation)
.onTapGesture
{
withAnimation(.easeOut(duration: 0.3))
{
self.isZoom.toggle()
}
}
Spacer()
}
.padding(10)
.background(Color.gray.opacity(0.3))
}
}
}
}