今回は, Viewのアニメーション(回転と拡大・縮小)について初歩的なものを扱っていきます.
環境は,
- macOS Catalina 10.15.7
- Xcode 12.0.1
- Swift 5.3
- iOS 14.0
です.
目次
rotationEffect
rotationEffectはViewを回転させるものです. 時計回りに回転します. 度数法で指定します.
View().rotationEffect(Angle(degrees: 角度))
import SwiftUI
struct ContentView: View {
var body: some View {
Text("ABCDEF")
.font(.largeTitle)
.rotationEffect(Angle(degrees: 30.0))
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}

rotationEffectはデフォルトではViewの中心を「回転の中心」として回転します. 回転の中心を指定することもできます. その際の位置指定はUIPointを使います.
UnitPointは, x座標とy座標を0から1までの値で指定します. (0, 0)は左上です. 例えば,
(x: 0.0, y: 0.0) | Viewの左上 |
(x: 1.0, y: 0.0) | Viewの右上 |
(x: 0.0, y: 1.0) | Viewの左下 |
(x: 1.0, y: 1.0) | Viewの右下 |
(x: 0.0, y: 0.0) | Viewの中央 |
となります. マイナス値や1.0より大きい数を指定することもできますが, View Frameの外側になります.
また, 次のような指定をすることもできます.
値 | 説明 |
---|---|
topLeading | 左上を回転の中心として回転させる |
top | 上辺中央を回転の中心として回転させる |
topTrailing | 右上を回転の中心として回転させる |
bottomLeading | 左下を回転の中心として回転させる |
bottom | 下辺中央を回転の中心として回転させる |
bottomTrailing | 右下を回転の中心として回転させる |
leading | 左辺中央を回転の中心として回転させる |
trailing | 右辺中央を回転の中心として回転させる |
center | 中央を回転の中心として回転させる |
import SwiftUI
struct ContentView: View {
var body: some View {
VStack(spacing: 90.0) {
Text("ABCDEF")
.font(.largeTitle)
.rotationEffect(Angle(degrees: 30.0), anchor: .topTrailing)
.border(Color.gray)
Text("ABCDEF")
.font(.largeTitle)
.rotationEffect(Angle(degrees: 30.0), anchor: .top)
.border(Color.gray)
Text("ABCDEF")
.font(.largeTitle)
.rotationEffect(Angle(degrees: 30.0), anchor: .leading)
.border(Color.gray)
Text("ABCDEF")
.font(.largeTitle)
.rotationEffect(Angle(degrees: 30.0), anchor: .trailing)
.border(Color.gray)
Text("ABCDEF")
.font(.largeTitle)
.rotationEffect(Angle(degrees: 30.0), anchor: .bottom)
.border(Color.gray)
}
}
}

rotation3DEffect
指定された回転の中心を中心として3D回転します.
具体例を見たほうが早いかもしれません.
import SwiftUI
struct ContentView: View {
@State private var degrees = 0.0
var body: some View {
VStack(spacing:100.0) {
Text("ABCDEFGH")
.font(.largeTitle)
.rotation3DEffect(.degrees(45), axis: (x: 1, y: 0, z: 0))
.border(Color.gray)
Text("ABCDEFGH")
.font(.largeTitle)
.rotation3DEffect(.degrees(45), axis: (x: 0, y: 1, z: 0))
.border(Color.gray)
Text("ABCDEFGH")
.font(.largeTitle)
.rotation3DEffect(.degrees(45), axis: (x: 0, y: 0, z: 1))
.border(Color.gray)
Text("ABCDEFGH")
.font(.largeTitle)
.rotation3DEffect(.degrees(45), axis: (x: 1, y: 1, z: 1))
.border(Color.gray)
}
}
}

rotation3DEffectはわからないことも多いので, SwiftUI 徹底入門

を参考に, 値を自由に動かせるものを作ってみました.
import SwiftUI
struct ContentView: View {
//プロパティの設定
@State private var angle = Angle(degrees: 0.0)
@State private var axisX: CGFloat = 0.0
@State private var axisY: CGFloat = 0.0
@State private var axisZ: CGFloat = 0.0
@State private var anchorZ: CGFloat = 0.0
@State private var perspective: CGFloat = 1.0
var body: some View {
VStack {
Spacer()
Image(systemName: "hare.fill")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 200)
.foregroundColor(Color.blue)
.rotation3DEffect(angle,
axis: (x: axisX, y: axisY, z: axisZ),
anchorZ: anchorZ,
perspective: perspective)
Spacer()
//回転角の設定
HStack{
Text("回転角:\(angle.degrees, specifier: "%.0f")°")
Slider(value: $angle.degrees, in: 0...360)
Stepper("",value: $angle.degrees, in: 0...360, step: 10)
}
//x軸
HStack {
Text("x:\(axisX, specifier: "%.1f")")
Slider(value: $axisX, in: 0...1)
Stepper("", value: $axisX, in: 0.0...1.0, step: 0.1)
}
//y軸
HStack {
Text("y:\(axisY, specifier: "%.1f")")
Slider(value: $axisY, in: 0...1)
Stepper("", value: $axisY, in: 0.0...1.0, step: 0.1)
}
//z軸
HStack {
Text("z:\(axisZ, specifier: "%.1f")")
Slider(value: $axisZ, in: 0...1)
Stepper("", value: $axisZ, in: 0.0...1.0, step: 0.1)
}
HStack {
Text("anchorZ:\(anchorZ, specifier: "%.0f")")
Slider(value: $anchorZ, in: -300...1000)
Stepper("", value: $anchorZ, in: -300...1000, step: 20)
}
HStack(alignment: .center) {
Text("perspective:\(perspective, specifier: "%.1f")")
Slider(value: $perspective, in: -5...5)
Stepper("", value: $perspective, in: -5...5, step: 0.1)
}
.padding(.bottom, 20)
Button("Reset") {
self.angle.degrees = 0.0
self.axisX = 0.0
self.axisY = 0.0
self.axisZ = 0.0
self.anchorZ = 0.0
self.perspective = 1.0
}
.padding(10)
.foregroundColor(Color(hue: 0.747, saturation: 0.976, brightness: 0.834))
.background(Color.yellow)
}
.font(.title3)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}


scaleEffect
scaleEffectはViewの拡大・縮小を行います. x軸方向とy軸方向を別々に指定することができます.
View().scaleEffect(倍率)
View().scaleEffect(x: x軸方向の倍率, y: y軸方向の倍率)
import SwiftUI
struct ContentView: View {
var body: some View {
VStack(spacing: 30.0) {
Text("ABCDEF")
Text("ABCDEF")
.scaleEffect(3.0)
}
}
}

import SwiftUI
struct ContentView: View {
var body: some View {
Text("ABCDEF")
.font(.largeTitle)
.scaleEffect(x: 0.75, y: 5.0)
}
}

相似の中心(拡大・縮小の中心のとなる点)を変更することも可能です.
View().scaleEffect(x: x軸方向の倍率, y: y軸方向の倍率, ancchor: 相似の中心)
相似の中心はUnitPointで指定します.
import SwiftUI
struct ContentView: View {
var body: some View {
ZStack{
Text("ABCDEF")
.font(.title)
.foregroundColor(Color.red)
Text("ABCDEF")
.font(.title)
.scaleEffect(x: 2.0, y: 2.0, anchor: UnitPoint(x: 0.5, y: 0.5))
}
}
}

import SwiftUI
struct ContentView: View {
var body: some View {
ZStack{
Text("ABCDEF")
.font(.title)
.foregroundColor(Color.red)
Text("ABCDEF")
.font(.title)
.scaleEffect(x: 2.0, y: 2.0, anchor: UnitPoint(x: 1, y: 0))
}
}
}

コメント