SwiftUIのHStackを使って要素を並べるときに、同じサイズをつかって、並べたいと思うことがよくあります。
.frameを使うのも1つですが、このPostで、良い方法が説明されていたので、メモ
問題点:要素のサイズがそれぞれ違う
数値を横一列に表示するようなケースだと、以下のようなコードになるかと思います。
struct ContentView: View {
let numbers: [Int] = [34, 21, 1, 97, 11]
var body: some View {
HStack {
ForEach(self.numbers, id: \.self) { num in
Text(String(num))
.padding(4)
.background(Color.orange)
.cornerRadius(5)
}
}
}
}
表示は、以下のようになります。
文字のサイズからそれぞれの大きさが計算されるので、1と97では、表示要素の大きさが違っています。同じ2桁の数字でも、34と11では違います。
文字列の一部として表示されるときは、綺麗な表示ということになりますが、要素を一列に並べたいときは、同じ大きさに揃えたくなります。
.frame
1番目に思いつくのが、外から数値指定してしまうことです。.frame を使うと以下のようになります。
struct ContentView: View {
let numbers: [Int] = [34, 21, 1, 97, 11]
var body: some View {
HStack {
ForEach(self.numbers, id: \.self) { num in
Text(String(num))
.frame(width: 30, height: 30)
.background(Color.orange)
.cornerRadius(5)
}
}
}
}
表示は以下のようになります。
実は、この方法にも問題点があります。システム設定でフォントサイズを大きくしていると、以下のような表示になってしまいます。
.overlay
この方法を考えた人は、TemplateViewと呼んでいますが、以下のような形で、要素を大きさを揃えることもできます。
struct ContentView: View {
let numbers: [Int] = [34, 21, 1, 97, 11]
var body: some View {
HStack {
ForEach(self.numbers, id: \.self) { num in
Text("121") // ⬅️ 調整余地あり
.hidden()
.padding(5)
.background(Color.orange)
.cornerRadius(5)
.overlay(Text(String(num)))
}
}
}
}
表示は以下のようになります。
この方法を使うと、システム設定でフォントサイズを大きくしても、それにつれて大きくなりますので、表示に問題は発生しません
しいて検討項目をあげると、テンプレートとしている文字列によって、表示要素の大きさが代わりますので、きちんと検討しないといけません。
例えば、ここで、”1″とかしてしまうと、”…”が再び現れます。
表示要素を揃えたいケースは非常に多いと思いますので、非常に有用なテクニックかと思います。特に書きませんでしたが、横方向だけではなく、縦方向も同様に揃います(揃っちゃいます)。
Sponsor Link