SwiftUIのHStackを使って要素を並べるときに、同じサイズをつかって、並べたいと思うことがよくあります。
.frameを使うのも1つですが、このPostで、良い方法が説明されていたので、メモ
問題点:要素のサイズがそれぞれ違う
数値を横一列に表示するようなケースだと、以下のようなコードになるかと思います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
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 を使うと以下のようになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
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と呼んでいますが、以下のような形で、要素を大きさを揃えることもできます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
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