独自のビューを定義してコードの見通しをよくする
この記事は下記の記事の発展形です。
上記の記事では、スライダ機能やテキスト機能を独自ビューで定義しただけですが、本記事では
「レクタングル Rectangle とテキスト Text 」
「スライダ Sliderとテキスト Text 」
としてまとめたビューをユーザ定義して、さらにコードの見通しをよくしてみます。
独自のビューは MyRectangleAndText と MyTextAndSlider という名前で定義します。
60行目、MyRectangleAndText は、Rectangle と Text を包含しています。
107行目、MyTextAndSlider は、Text と Slider を包含しています。
24 〜 57行目の var body: some View{} が極めて簡潔に記述できていることに注目してください。
MyRectangleAndText や MyTextAndSlider のコードの中でコメントしていますが、VStack を HStack や ZStack に書き換えるとそれに応じて画面の見た目が変更されることをぜひ確認してみてください。
MyRectangleAndText の中身の配置は ZStack にするとかっこいいのですが Text の色がデフォルトの Color.black なので、Text は Rectangle の塗りつぶし色の反対色にしないとまずいですね。
import SwiftUI
struct SLIDER {
static let MIN: Double = 0.0
static let MAX: Double = 255.0
static let STEP: Double = 1.0
}
struct ContentView: View {
@State var FlagNowEditingR = false
@State var FlagNowEditingG = false
@State var FlagNowEditingB = false
@State var FlagNowEditingA = false
@State var SliderR: Double = 32.0 * 1
@State var SliderG: Double = 32.0 * 3
@State var SliderB: Double = 32.0 * 5
@State var SliderA: Double = 32.0 * 7
let RECT_W = 240.0
let RECT_H = 160.0
var body: some View {
Spacer()
VStack {
MyRectangleAndText(
r_0_to_255: SliderR,
g_0_to_255: SliderG,
b_0_to_255: SliderB,
a_0_to_255: SliderA,
rectangle_w: RECT_W,
rectangle_h: RECT_H
)
}
Spacer()
VStack {
MyTextAndSlider( value: $SliderR, flag_now_editing: $FlagNowEditingR, color_name: "R" )
MyTextAndSlider( value: $SliderG, flag_now_editing: $FlagNowEditingG, color_name: "G" )
MyTextAndSlider( value: $SliderB, flag_now_editing: $FlagNowEditingB, color_name: "B" )
MyTextAndSlider( value: $SliderA, flag_now_editing: $FlagNowEditingA, color_name: "A" )
}
.padding( 30.0 )
Spacer()
}
}
// 独自のレクタングルとテキスト.
struct MyRectangleAndText: View {
var r_0_to_255: Double
var g_0_to_255: Double
var b_0_to_255: Double
var a_0_to_255: Double
var rectangle_w: Double
var rectangle_h: Double
var body: some View {
// ZStack や HStasck にして効き目を確認すること.
VStack{
// 色成分は 0.0 〜 1.0 で指定する.
let r_0_to_1 = Double( r_0_to_255 )/Double( 255.0 )
let g_0_to_1 = Double( g_0_to_255 )/Double( 255.0 )
let b_0_to_1 = Double( b_0_to_255 )/Double( 255.0 )
let a_0_to_1 = Double( a_0_to_255 )/Double( 255.0 )
let the_color = Color(
red: r_0_to_1,
green: g_0_to_1,
blue: b_0_to_1,
opacity: a_0_to_1
)
// 指定した色で塗りつぶした矩形を表示する.
Rectangle()
.stroke( .black, lineWidth: 2.0 )
.background( the_color )
.frame(width: rectangle_w, height: rectangle_h )
// 0 〜 255 で表示する.
let r = Int( r_0_to_255.rounded() )
let g = Int( g_0_to_255.rounded() )
let b = Int( b_0_to_255.rounded() )
let a = Int( a_0_to_255.rounded() )
Text( String( format: "RGBA( %d, %d, %d, %d )", r, g, b, a ) )
}
}
}
// 独自のテキストとスライダをワンセット.
struct MyTextAndSlider: View {
@Binding var value: Double
@Binding var flag_now_editing: Bool
var color_name: String
var body: some View {
// HStack や ZStasck にして効き目を確認すること.
VStack{
Text( String( format: "%@ is %.1f", color_name, value ))
.foregroundColor( flag_now_editing ? .red : .black )
Slider(
value: $value,
in: SLIDER.MIN...SLIDER.MAX,
step: SLIDER.STEP,
onEditingChanged: {
editing in
flag_now_editing = editing
}
)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}