#【SwiftUI】ビューをジェスチャーで回転させ、90°ずつスナップを効かせる方法
こんにちは、たいちです(@taichi_swift_)
たかし「お絵かきアプリとかでよくある、ビューを回転させて90°づつピタって止めるやつ、どうやって実装するんだろ...」
こちらのお悩みを解決します。
##ビューを回転させる方法
まずは、基本のビューを回転させる方法です。
SwiftUIでは、
.rotationEffect(_ angle: Angle, anchor: UnitPoint = .center)
というmodifierを使用します。
実際に使うときには、
.rotationEffect(Angle(degrees: 90))
みたいに使うわけですね。
Text("RotationEffect")
.rotationEffect(Angle(degrees: 90))
##ビューをジェスチャーで回転させる方法
続いて、ユーザーが指を使ってビューを回転させる方法です。
.gesture()
を使います。
まずは、角度を格納する変数を2つ用意します。
@State var angle = Angle(degrees: 0.0)
@State private var oldAngle = Angle(degrees: 0.0)
そして、ジェスチャーを用意します
var rotation: some Gesture {
RotationGesture()
.onChanged { angle in
self.angle = self.oldAngle + angle
}
.onEnded { angle in
self.oldAngle = self.angle
}
}
そんでこのジェスチャーをテキトーなビューにがっちゃんこします。
.rotationEffect(self.angle)
.gesture(rotation)
RoundedRectangle(cornerRadius: 20)
.frame(width: 400, height: 300)
.rotationEffect(self.angle)
.gesture(rotation)
##ビューを回転させ、スナップさせる方法
やっときました。本題です。
先ほど定義した、rotationという名前のgestureにちょこっと細工を加えてあげます。
var rotation: some Gesture {
RotationGesture()
.onChanged { angle in
self.angle = self.oldAngle + angle
if abs(Int(self.angle.degrees) % 90) < 5 {
self.angle = Angle(degrees: Double(Int(self.angle.degrees) - Int(self.angle.degrees) % 90))
}
}
.onEnded { angle in
self.oldAngle = self.angle
}
}
完成です。
struct ContentView: View {
@State var angle = Angle(degrees: 0.0)
@State private var oldAngle = Angle(degrees: 0.0)
var rotation: some Gesture {
RotationGesture()
.onChanged { angle in
self.angle = self.oldAngle + angle
if abs(Int(self.angle.degrees) % 90) < 5 {
self.angle = Angle(degrees: Double(Int(self.angle.degrees) - Int(self.angle.degrees) % 90))
}
}
.onEnded { angle in
self.oldAngle = self.angle
}
}
var body: some View {
RoundedRectangle(cornerRadius: 20)
.frame(width: 400, height: 300)
.rotationEffect(self.angle)
.gesture(rotation)
}
}