diff --git a/Example/Example/ContentModeExample.swift b/Example/Example/ContentModeExample.swift index 614e741..872509c 100644 --- a/Example/Example/ContentModeExample.swift +++ b/Example/Example/ContentModeExample.swift @@ -16,19 +16,30 @@ struct ContentModeExample: View { let color = GridColor.random.lighter(by: 50) } - @State var contentMode: GridContentMode = .scroll + @State var contentMode: GridContentMode = .contentFit var body: some View { VStack { self.modesPicker + if self.contentMode == .contentFit { + ScrollView { + myView + } + } else { + myView + } + } + } + + var myView: some View { Grid(models, id: \.self, tracks: 3) { VCardView(text: $0.text, color: $0.color) .gridSpan($0.span) } .gridContentMode(self.contentMode) .gridFlow(.rows) - } + .background(Color.blue) } private let models: [Model] = [ @@ -46,9 +57,12 @@ struct ContentModeExample: View { private var modesPicker: some View { Picker("Mode", selection: $contentMode) { - ForEach([GridContentMode.scroll, GridContentMode.fill], id: \.self) { - Text($0 == .scroll ? "Scroll" : "Fill") - .tag($0) + ForEach([GridContentMode.contentFit, GridContentMode.scroll, GridContentMode.fill], id: \.self) { + switch($0) { + case .contentFit: Text("ContentFit").tag($0) + case .scroll: Text("Scroll").tag($0) + case .fill: Text("Fill").tag($0) + } } } .pickerStyle(SegmentedPickerStyle()) diff --git a/Sources/GridLayoutMath/LayoutPositioning.swift b/Sources/GridLayoutMath/LayoutPositioning.swift index d802c68..39a1fc2 100644 --- a/Sources/GridLayoutMath/LayoutPositioning.swift +++ b/Sources/GridLayoutMath/LayoutPositioning.swift @@ -56,6 +56,8 @@ extension LayoutPositioning { let growingTracks: [GridTrack] let growingBoundingSize: CGFloat switch task.contentMode { + case .contentFit: + fallthrough case .scroll: growingTracks = [GridTrack](repeating: .fit, count: arrangement[keyPath: flow.arrangementCount(.growing)]) growingBoundingSize = .infinity @@ -187,6 +189,8 @@ extension LayoutPositioning { let growingSize = boundingSize[keyPath: flow.size(.growing)] / CGFloat(arrangement[keyPath: flow.arrangementCount(.growing)]) itemGrowingSize = growingSize * CGFloat(arrangedItem[keyPath: flow.arrangedItemCount(.growing)]) growingPosition = growingSize * CGFloat(arrangedItem.startIndex[keyPath: flow.index(.growing)]) + case .contentFit: + fallthrough case .scroll: let indexRange = arrangedItem.startIndex[keyPath: flow.index(.growing)]...arrangedItem.endIndex[keyPath: flow.index(.growing)] itemGrowingSize = indexRange.reduce(0, { result, index in diff --git a/Sources/Models/GridContentMode.swift b/Sources/Models/GridContentMode.swift index 9b3ab16..797f788 100644 --- a/Sources/Models/GridContentMode.swift +++ b/Sources/Models/GridContentMode.swift @@ -13,6 +13,9 @@ public enum GridContentMode { /// Scrolls inside parent container case scroll + /// Fits the content + case contentFit + /// Fills the entire space of the parent container case fill } diff --git a/Sources/View/Grid.swift b/Sources/View/Grid.swift index 2d59566..a87ba3c 100644 --- a/Sources/View/Grid.swift +++ b/Sources/View/Grid.swift @@ -135,6 +135,9 @@ public struct Grid: View, LayoutArranging, LayoutPositioning { self.saveAlignmentsFrom(preference: preference) } } + .if(contentMode == .contentFit) { content in + content.frame(height: self.positions.totalSize?.height ?? 0) + } .id(self.isLoaded) } @@ -204,6 +207,8 @@ public struct Grid: View, LayoutArranging, LayoutPositioning { switch self.contentMode { case .fill: return [] + case .contentFit: + fallthrough case .scroll: return self.flow == .rows ? .vertical : .horizontal } @@ -268,6 +273,8 @@ extension View { case .fill: width = size?.width height = size?.height + case .contentFit: + fallthrough case .scroll: width = (flow == .rows ? size?.width : nil) height = (flow == .columns ? size?.height : nil)