🔧
iOS15にてLazyVGrid子要素の高さが揃わない問題と対策
iOS14.5では、LazyVGridの子要素は高さが揃いますが
iOS15からは、おそらくバグで高さが揃わなくなっています。
StackOverflowにも同様の報告上がっています。
LazyVGridで解決するのは難しい可能性が高いので
今回はHStackを利用しました。
import SwiftUI
struct MaximumHeightPreferenceKey: PreferenceKey {
static var defaultValue: CGFloat = 0
static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {
value = max(value, nextValue())
}
}
struct DetermineHeight: View {
typealias Key = MaximumHeightPreferenceKey
var body: some View {
GeometryReader { proxy in
Color.clear
.anchorPreference(key: Key.self, value: .bounds) { anchor in
proxy[anchor].size.height
}
}
}
}
struct ContentView: View {
@State var maximumSubViewHeight: CGFloat = 0
let columns: [GridItem] = Array(repeating: .init(.flexible()), count: 2)
var body: some View {
HStack {
Group {
Text("Hello")
.border(.red)
.overlay(DetermineHeight())
}
.frame(minHeight: maximumSubViewHeight, alignment: .bottom)
Group {
Text("Lorem\nipsum")
.border(.blue)
.overlay(DetermineHeight())
}
.frame(minHeight: maximumSubViewHeight, alignment: .bottom)
}
.border(.green)
.padding(.horizontal, 100)
.onPreferenceChange(DetermineHeight.Key.self) {
maximumSubViewHeight = $0
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
※ このコードは大部分をWooji Juice社様の記事を参考にさせて頂いております。
PreferenceKeyやminHeightを利用して上手く問題に対処しているように見えます。
そして、このようにiOS14.5でもiOS15でも動作します。
ただ、HStackだとLazyVGridのように多数のデータを列に並べるなどを満たしません。
ここはLazyVGridに渡す配列の代わりに、配列を2つづchunk化して
HStackに例えば2個づつ渡すような実装で対応を行いました。
// コードのイメージ
ForEach(items.chunked(by: 2), id: \.id) { chunk in
GirdPartView(chunk)
}
chunked実装は、このようなイメージなります。
Discussion