【SwiftUI】Viewを左右・上下反転、45°回転させる

2022.04.14

今回はViewを左右反転したり、上下反転したり、45°回転させたりする方法を紹介します。

作ったもの

FlipViewPractice

今回は、rotationEffect(_:anchor:)rotation3DEffect(_:axis:anchor:anchorZ:perspective:)モディファイアを使用して実現しています。

rotationEffect(_:anchor:)

func rotationEffect(_ angle: Angle, anchor: UnitPoint = .center) -> some View
  • angle
    • Viewを回転させる角度
  • anchor
    • 回転の軸となるポイント。デフォルトで.centerになっており、今回はデフォルト値で使用します。

rotation3DEffect(_:axis:anchor:anchorZ:perspective:)

func rotation3DEffect(_ angle: Angle,
                      axis: (x: CGFloat, y: CGFloat, z: CGFloat),
                      anchor: UnitPoint = .center,
                      anchorZ: CGFloat = 0,
                      perspective: CGFloat = 1) -> some View
  • angle
    • Viewを回転させる角度
  • axis
    • 回転軸を指定するx、y、z
  • anchor
    • 3D空間内で回転の軸になるポイント。デフォルトは.center
  • anchorZ
    • 3D空間内で回転の軸となるz方向のポイント。デフォルト値は0
  • perspective
    • 相対的な消失点の値

axis

今回はaxisが重要なので図で説明します。

3D座標系

x, y, zの3D座標系の図になります。

3D座標系には右手座標系と左手座標系があり、左手座標系では時計回り、右手座標系では反時計回りが正の回転方向として定められています。

基本的には右手座標系が標準とされており、今回のケースも右手座標系が適用されています。

今回の人型のImageを当てはめてみるとこのようになります。

  • x軸: 横方向の座標軸
  • y軸: 縦方向の座標軸
  • z軸: 奥行方向の座標軸

x、y、zがそれぞれ上記の軸となっております。

左右を反転させる

左右を反転させたいので、y軸を回転軸にして180°回転させます。

Image(systemName: "figure.walk")
    .resizable()
    .scaledToFit()
    .frame(width: 200)
    .rotation3DEffect(.degrees(180),
                      axis: (x: 0, y: 1, z: 0))

上下を反転させる

上下を反転させたいので、x軸を回転軸にして180°回転させます。

Image(systemName: "figure.walk")
    .resizable()
    .scaledToFit()
    .frame(width: 200)
    .rotation3DEffect(.degrees(180),
                      axis: (x: 1, y: 0, z: 0))

上下左右を反転させる

上下左右を反転させたような状態にしたいので、z軸を回転軸にして180°回転させます。

Image(systemName: "figure.walk")
    .resizable()
    .scaledToFit()
    .frame(width: 200)
    .rotation3DEffect(.degrees(180),
                      axis: (x: 0, y: 0, z: 1))

rotationEffect(.degrees(180))を使用する

rotationEffectを使用して回転させた際も、rotation3DEffectaxisでz軸を回転軸にした時のように回転させることが出来ます。デフォルトでは.centerが軸になっているので180°回転させます。

Image(systemName: "figure.walk")
    .resizable()
    .scaledToFit()
    .frame(width: 200)
    .rotationEffect(.degrees(180))

45°回転させる

rotationEffect(.degrees(180))を使用するでも触れたのですが、対象を平面で回転させたい場合はrotationEffect(_:anchor:)を使用します。

Image(systemName: "figure.walk")
    .resizable()
    .scaledToFit()
    .frame(width: 200)
    .rotationEffect(.degrees(45))

下記ではボタンを押すと回転角度が45ずつインクリメントするように実装しています。

FlipViewPractice-rotation

サンプルコード

今回のデモのコードはGitHubに置いてあります。

おわりに

Viewの反転を通して、x,y,z軸について少し理解が深まった気がしました。

引き続き、3D座標系のゆるキャラ エックスワイゼットンのことをよろしくお願いします。

参考