Created
November 5, 2021 16:28
-
-
Save mayoff/260e019f307dfcb55f00e40a227a4225 to your computer and use it in GitHub Desktop.
Revisions
-
mayoff created this gist
Nov 5, 2021 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,134 @@ import SwiftUI fileprivate struct WidthPreferenceKey: PreferenceKey { static var defaultValue: [AnyHashable: CGFloat] { [:] } static func reduce(value: inout [AnyHashable : CGFloat], nextValue: () -> [AnyHashable : CGFloat]) { value.merge(nextValue(), uniquingKeysWith: { max($0, $1) }) } } extension WidthPreferenceKey: EnvironmentKey { } extension EnvironmentValues { fileprivate var widthPreference: WidthPreferenceKey.Value { get { self[WidthPreferenceKey.self] } set { self[WidthPreferenceKey.self] = newValue } } } extension View { public func widthPreference<Domain: Hashable>(_ key: Domain) -> some View { return self.modifier(WidthPreferenceModifier(key: key)) } } fileprivate struct WidthPreferenceModifier: ViewModifier { @Environment(\.widthPreference) var widthPreference var key: AnyHashable func body(content: Content) -> some View { content .fixedSize(horizontal: true, vertical: false) .background(GeometryReader { proxy in Color.clear .preference(key: WidthPreferenceKey.self, value: [key: proxy.size.width]) }) .frame(width: widthPreference[key]) } } public struct WidthPreferenceDomain<Content: View>: View { @State private var widthPreference: WidthPreferenceKey.Value = [:] private var content: Content public init(@ViewBuilder content: () -> Content) { self.content = content() } public var body: some View { content .environment(\.widthPreference, widthPreference) .onPreferenceChange(WidthPreferenceKey.self) { widthPreference = $0 } } } struct ContentView: View { var body: some View { VStack(spacing: 0) { ZStack { TitleBackground() Text("Clients") .foregroundColor(.white) } TableView() Spacer() } } } enum ColumnId: Hashable { case name case balance case currency } struct TableView: View { var body: some View { WidthPreferenceDomain { VStack(spacing: 0) { HStack(spacing: 30) { Text("Name") .widthPreference(ColumnId.name) Text("Balance") .widthPreference(ColumnId.balance) Text("Currency") .widthPreference(ColumnId.currency) Spacer() } .frame(maxWidth:.infinity) .padding(12) .background(Color(#colorLiteral(red: 0.9332349896, green: 0.9333916306, blue: 0.9332130551, alpha: 1))) ForEach(0 ..< 4) { _ in RowView() } } } } } struct RowView : View { var body: some View { HStack(spacing: 30) { Text("John") .widthPreference(ColumnId.name) Text("$5300") .widthPreference(ColumnId.balance) Text("EUR") .widthPreference(ColumnId.currency) Spacer() } .padding(12) } } struct TitleBackground: View { var body: some View { ZStack(alignment: .bottom){ Rectangle() .frame(maxWidth: .infinity, maxHeight: 60) .foregroundColor(.red) .cornerRadius(15) //We only need the top corners rounded, so we embed another rectangle to the bottom. Rectangle() .frame(maxWidth: .infinity, maxHeight: 15) .foregroundColor(.red) } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }