ZStackにおけるViewについて考察する(001,内側外側で背景色を変える)
Rectangle をタップしてその位置は、内側か外側かを判定して、背景色を変化させる方法を紹介します。
この記事は、下記に示す記事の続きです。所望のビューのタップジェスチャが、やや外側でも反応することに注意してください。
最背面に、Bool なフラグを判定して色を変化させる Rectangle を配置します。
その上に、タップ座標を取得できるRectangle を配置します。
そして、その上に変数を表示するための VStack で管理された Text を配置します。
ZStack の上に載せているので、それらはすべて画面の中心に配置されます。
下記のコードの11、12行目で、内側をタップしたときと、外側をタップしたときの色を決めています。
27行目が最背面にある Rectangle の色を決定しているところで、FlagInsideRect という Bool 値を評価して、三項演算子を使って自身の色を変化させています。また、Rectangle は .frame モディファイヤを指定しなければ画面いっぱいのサイズで配置されます。
Text の上をタップしても、座標に変化がないことに気づくと思います。これは Text の下にタップジェスチャに反応する Rectangle が配置されているからです。ビューを透過してタップジェスチャを効かせる方法は、また別の記事で考察しようと思います。
import SwiftUI
struct ContentView: View {
let RECT_W: CGFloat = 320
let RECT_H: CGFloat = 640
let COLOR_RECT: Color = Color.blue
let COLOR_TEXT: Color = Color.white
let COLOR_INSIDE: Color = Color( red: 0x00, green: 0xff, blue: 0x00, opacity: 0xff )
let COLOR_OUTSIDE: Color = Color( red: 0xff, green: 0x00, blue: 0x00, opacity: 0xff )
@State var TapX: CGFloat = 0.0
@State var TapY: CGFloat = 0.0
@State var InsideRectTapX: CGFloat = 0.0
@State var InsideRectTapY: CGFloat = 0.0
@State var FlagInsideRect = true
var body: some View {
ZStack{
// 最背面.
Rectangle()
.foregroundColor( FlagInsideRect ? COLOR_INSIDE : COLOR_OUTSIDE )
// 中層面.
Rectangle()
.frame( width: RECT_W, height: RECT_H ) // サイズを指定する.
.foregroundColor( COLOR_RECT ) // 色を指定する.
.onTapGesture {
tap in
TapX = tap.x
TapY = tap.y
// いったんそのままタップ座標を代入する.
InsideRectTapX = TapX
InsideRectTapY = TapY
// いったんフラグを真にしておく.
FlagInsideRect = true
// Rectangleの内側か外側か判定して InsideRectTapXとY を調整する.
if ( InsideRectTapX < 0.0 ){
InsideRectTapX = 0.0;
FlagInsideRect = false
}
if ( InsideRectTapY < 0.0 ){
InsideRectTapY = 0.0
FlagInsideRect = false
}
if ( InsideRectTapX >= RECT_W ){
InsideRectTapX = RECT_W - 1
FlagInsideRect = false
}
if ( InsideRectTapY >= RECT_H ){
InsideRectTapY = RECT_H - 1
FlagInsideRect = false
}
}
// 最前面.
VStack{
Text( String( format: "TapXY( %.1f, %.1f )", TapX, TapY ))
.foregroundColor( COLOR_TEXT )
Text( String( format: "InsideRectTapXY( %.1f, %.1f )", InsideRectTapX, InsideRectTapY ))
.foregroundColor( COLOR_TEXT )
Text( String( format: "FlagInsideRect is %d", FlagInsideRect ))
.foregroundColor( COLOR_TEXT )
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}