Sponsor Link
環境&対象
- macOS Ventura 13.3
- Xcode 14.3 RC
- iOS 16.4 beta
LabeledContent
iOS16/macOS13 で導入された SwiftUI の新しい View です。
Apple のドキュメントは、こちら。
ある値を表示する時に説明表示と合わせて表示するための View です。
LabeledContent 以前は、各種 Stack や ViewModifier を使用して 見た目的に 関係性が見えるように配置していました。
LabeledContent では、説明側を label、値を content や value として指定します。以下の例は、content として指定しています。
struct ContentView: View {
@State private var pickerValue: Int = 0
var body: some View {
Group {
LabeledContent(content: {
Text("Content")
}, label: { Text("Label") })
.border(.red)
}
.padding()
}
}
iOS/macOS で以下のような表示になります。
# 表示範囲をわかりやすくするために、.border(.red) を指定しています。
# macOS での表示が少し期待と違う気がしますが、それは後ほど。
値を渡して FormatStyle を使って表示する
先の例では、値を content 指定して 直接表示に使用する View を渡していましたが、value 指定を使うことで、FormatStyle を使って変換したものを表示に使うことができます。
value 指定では、View を指定するのではなく、データそのものを渡すことができます。例えば、Double の値や Decimal の値をそのまま渡すということです。
その時に、どのように表示するかの指定を FormatStyle で指定します。
例えば、以下のコードは、2000 というDecimal を通貨表示する指定を行っています。
LabeledContent("Value", value: Decimal(2000),
format: .currency(code: "JPY"))
表示は以下のようになります。
LabeledContentStyle
サンプルのコードで表示した LabeledContent を見てみると iOS と macOS で表示の仕方が異なることがわかります。
iOS では、ラベルは左側が揃えられ、値は右側が揃えられています。そして、ラベルは、使用可能な領域の左に寄せられ、値は、領域の右に寄せられています。
macOS では、ラベルの右側が揃えられ、値は、左側が揃えられています。そして、ラベルと値は、一定の間隔を空けて並べられています。
iOS/macOS それぞれ ルールが異なるのかと思ったのですが、例えば、macOS の システム設定を見てみると macOS でも iOS 流の整列方法を使用しています。
個人的にも macOS であっても iOS 流の整列方法で表示したいケースが多そうだと感じます。
ということで、iOS 流の表示にカスタマイズしていきます。
LabeledContent のカスタマイズ
SwiftUI では、さまざまな View のカスタマイズを Style を使って行います。LabeledContent についても 同様にカスタマイズします。そのために、LabeledContentStyle が用意されています。
Apple のドキュメントは、こちら。
なお、実際の Style としては .automatic しか用意されていません。
説明も、context に応じて表示するとなっていて 謎です・・・
SplitLabeledContentStyle
さっそく、左右に分かれて表示されるようなスタイルを作ってみることにします。名前は、SplitLabeledContentStyle としました。
他の Style と同様に、実装すべきメソッドは、以下です。
@ViewBuilder func makeBody(configuration: Self.Configuration) -> Self.Body
Style 実装時に参照できる Configuration は、LabeledContentStyleConfiguration です。
Apple のドキュメントは、こちら。
label, content として指定したもの(相当)を 参照できるようになっています。
struct SplitLabeledContentStyle: LabeledContentStyle {
func makeBody(configuration: Configuration) -> some View {
HStack {
configuration.label
Spacer()
configuration.content
}
}
}
label と content を左右に分けて表示したいだけなので、実装は シンプル です。
この定義だけでも使えますが、このままだと、.labeledContentStyle で指定する時に長々(?) と指定しなければいけないので、以下の extension を定義して 短く指定できるようにしておきます。
extension LabeledContentStyle where Self == SplitLabeledContentStyle {
static var split: SplitLabeledContentStyle { .init() }
}
使用例
早速使ってみます。
struct ContentView: View {
@State private var pickerValue: Int = 0
var body: some View {
Group {
LabeledContent(content: {
Text("Content")
}, label: { Text("Label") })
.border(.red)
LabeledContent("Value", value: Decimal(2000),
format: .currency(code: "JPY"))
.border(.red)
}
.labeledContentStyle(.split)
.padding()
}
}
複数の LabeledContent に指定したいので、Group に対して指定しています。
macOS では、期待通りに 左右に広がって表示されていることが確認できます。iOS では、.automatic がもともとそのように表示される設定なので、変化はありません。
まとめ
iOS16/macOS13 で導入された LabeledContent をみてみました。説明ラベルと値をセットで表示する時に使用する View であることを確認し、LabeledContentStyle を使用して、表示のカスタマイズをしてみました。
- LabeledContent は、値を説明用ラベルを表示する View
- label: で説明用ラベルを指定する
- content: で値用 View を指定する
- value: を使うと、FormatStyle を使った変換を使用して表示される
- デフォルトでは、iOS と macOS で表示スタイルが異なる
- 表示のカスタマイズには、LabeledContentStyle を使用する
- extension 定義しておくと、簡単に指定できるようになって便利
説明は以上です。
不明な点やおかしな点ありましたら、こちらまで。
SwiftUI おすすめ本
SwiftUI を理解するには、以下の本がおすすめです。
SwiftUI ViewMatery
SwiftUI で開発していくときに、ViewやLayoutのための適切なmodifierを探すのが大変です。
英語での説明になってしまいますが、以下の”SwiftUI Views Mastery Bundle”という本がビジュアル的に確認して探せるので、便利です。
英語ではありますが、1ページに コードと画面が並んでいるので、非常にわかりやすいです。
View に適用できる modifier もわかりやすく説明されているので、ビューの理解だけではなく、どのような装飾ができるかも簡単にわかります。
超便利です
販売元のページは、こちらです。
SwiftUI 徹底入門
# SwiftUI は、毎年大きく改善されていますので、少し古くなってしまいましたが、いまでも 定番本です。
Swift学習におすすめの本
詳解Swift
Swift の学習には、詳解 Swift という書籍が、おすすめです。
著者は、Swift の初期から書籍を出していますし、Swift の前に主力言語だった Objective-C という言語についても同様の書籍を出しています。
最新版を購入するのがおすすめです。
現時点では、上記の Swift 5 に対応した第5版が最新版です。
Sponsor Link