Sponsor Link
課題:Rectangle の左上の位置を指定して、配置したい
Rectangle を使っていて、position で位置を指定すると、中央の位置指定になってしまうのが、少し不便でした。
position で指定した位置に、小さい円を表示しています。
struct ContentView: View {
var body: some View {
ZStack {
Rectangle()
.fill(Color.yellow)
.frame(width:100, height:100, alignment: .topLeading)
.border(Color.red)
.position(x: 200, y: 100)
Circle()
.fill(Color.red)
.frame(width:10, height:10)
.position(x:200, y:100)
}
}
}
Rectangle を position 指定したときに、左上の位置を指定したい時があるので、簡単に指定できるようにしてみます。
ということで、ViewModifier を作って、便利にしたいと思います。
作りたいModifier
.TLposition(position: CGPoint, size: CGSize)で、Rectangle の左上が指定位置に来るように指定できるようにします。
View Modifier Protocol
ViewModifier というプロトコルを調べてみると、
“func body(content: Self.Content) -> Self.Body” というメソッドを実装する必要がありそうです。
さっそく実装
希望する位置とサイズから、位置を調整して、.position を使うようにしました。
struct TLPosition: ViewModifier {
let position: CGPoint
let size: CGSize
func body(content: Content) -> some View {
content
.frame(width: size.width, height: size.height)
.position(x: self.position.x + size.width/2,
y: self.position.y + size.height/2)
}
}
ViewModifier の使い方
作成した ViewModifier を使用することで、以下のような表示になります。
作成した ViewModifier は、そのまま、View へ適用することはできずに、.modifier という modifier を使って適用する必要があります。
struct ContentView: View {
var body: some View {
ZStack {
Rectangle()
.fill(Color.yellow)
.border(Color.red)
.modifier(TLPosition(position: CGPoint(x: 200, y: 100),
size: CGSize(width: 100, height: 100)))
Circle()
.fill(Color.red)
.frame(width:10, height:10)
.position(x:200, y:100)
}
}
}
View extension化して、より便利に
.modifier を使っても良いのですが、他の modifier と同じように使うためには、View の extension にする必要があります。
extension View {
func tlPosition(position: CGPoint, size: CGSize) -> some View {
self.modifier(TLPosition(position: position, size: size))
}
}
こうすることで、他の View modifier と同じように適用することができます。
struct ContentView: View {
var body: some View {
ZStack {
Rectangle()
.fill(Color.yellow)
.border(Color.red)
.tlPosition(position: CGPoint(x: 200, y: 100),
size: CGSize(width: 100, height: 100)) // ⬅️ NEW!
Circle()
.fill(Color.red)
.frame(width:10, height:10)
.position(x:200, y:100)
}
}
}
View の extension にしていることからもわかりますが、View に適用できる modifier しか使えません。
特定のView のみで使用できる modifier (例えば、Text の multilineTextAlignment ) を使いたいときには、直接その View の extension を作る必要があります。
まとめ: ViewModifier, View extension
このように、ViewModifier を継承して、カスタム modifier を作り、View extension を使うと、コードの可読性が格段に上がります。
うまくつかうと、再利用性、コード可読性、いずれもあげることができますので、うまく使いましょう。
Sponsor Link