Skip to content

Commit

Permalink
Improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
tevelee committed Dec 19, 2024
1 parent 599c97a commit 860e93e
Show file tree
Hide file tree
Showing 9 changed files with 85 additions and 50 deletions.
103 changes: 78 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,59 +99,112 @@ HFlow(itemSpacing: 4, rowSpacing: 20) {

![HFlow](Resources/hflow-spacing.png)

## Justified
## Distribute items

Justify by stretching items, the spaces between them, or both.
Distribute items evenly by minimizing the empty spaces left in each row.
Implements the Knuth-Plass line breaking algorithm.

```swift
HFlow(justification: .stretchItems) {
HFlow(distributeItemsEvenly: true) {
ForEach(colors, id: \.description) { color in
RoundedRectangle(cornerRadius: 10)
.fill(color.gradient)
.frame(height: 50)
.frame(minWidth: 35)
.frame(width: 65, height: 50)
}
}
.frame(width: 300)
.frame(width: 300, alignment: .leading)
```

![HFlow](Resources/hflow-justified.png)

---
![HFlow](Resources/hflow-distributed.png)

Distribute items evenly by minimizing the empty spaces left in each row.
Implements the Knuth-Plass line breaking algorithm.
## Justified

```swift
HFlow(distributeItemsEvenly: true) {
HFlow(justified: true) {
ForEach(colors, id: \.description) { color in
RoundedRectangle(cornerRadius: 10)
.fill(color.gradient)
.frame(width: 65, height: 50)
.frame(width: 50, height: 50)
}
}
.frame(width: 300, alignment: .leading)
.frame(width: 300)
```

![HFlow](Resources/hflow-distributed.png)
![HFlow](Resources/hflow-justified.png)

## Flexibility

```swift
HFlow { // distributes flexible items proportionally
RoundedRectangle(cornerRadius: 10)
.fill(.red)
.frame(minWidth: 50, maxWidth: .infinity)
.frame(height: 50)
.flexibility(.minimum) // takes as little space as possible, rigid
RoundedRectangle(cornerRadius: 10)
.fill(.green)
.frame(minWidth: 50, maxWidth: .infinity)
.frame(height: 50)
.flexibility(.natural) // expands
RoundedRectangle(cornerRadius: 10)
.fill(.blue)
.frame(minWidth: 50, maxWidth: .infinity)
.frame(height: 50)
.flexibility(.natural) // expands
RoundedRectangle(cornerRadius: 10)
.fill(.yellow)
.frame(minWidth: 50, maxWidth: .infinity)
.frame(height: 50) // takes as much space as possible
.flexibility(.maximum)
}
.frame(width: 300)
```

---
![HFlow](Resources/hflow-flexibility.png)

Distribute and justify for visually pleasing UI.
## Line breaks

```swift
HFlow(justification: .stretchItems, distributeItemsEvenly: true) {
ForEach(colors, id: \.description) { color in
RoundedRectangle(cornerRadius: 10)
.fill(color.gradient)
.frame(height: 50)
.frame(minWidth: 60)
}
HFlow {
RoundedRectangle(cornerRadius: 10)
.fill(.red)
.frame(width: 50, height: 50)
RoundedRectangle(cornerRadius: 10)
.fill(.green)
.frame(width: 50, height: 50)
RoundedRectangle(cornerRadius: 10)
.fill(.blue)
.frame(width: 50, height: 50)
LineBreak()
RoundedRectangle(cornerRadius: 10)
.fill(.yellow)
.frame(width: 50, height: 50)
}
.frame(width: 300)
```

![HFlow](Resources/hflow-linebreak.png)

```swift
HFlow {
RoundedRectangle(cornerRadius: 10)
.fill(.red)
.frame(width: 50, height: 50)
RoundedRectangle(cornerRadius: 10)
.fill(.green)
.frame(width: 50, height: 50)
.startInNewLine()
RoundedRectangle(cornerRadius: 10)
.fill(.blue)
.frame(width: 50, height: 50)
RoundedRectangle(cornerRadius: 10)
.fill(.yellow)
.frame(width: 50, height: 50)
}
.frame(width: 300)
```

![HFlow](Resources/hflow-justified-and-distributed.png)
![HFlow](Resources/hflow-newline.png)

## RTL

Expand Down
Binary file added Resources/hflow-flexibility.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed Resources/hflow-justified-and-distributed.png
Binary file not shown.
Binary file modified Resources/hflow-justified.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Resources/hflow-linebreak.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Resources/hflow-newline.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 4 additions & 22 deletions Sources/Flow/Example/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ struct ContentView: View {
@State private var height: CGFloat = 400
@State private var itemSpacing: CGFloat? = nil
@State private var lineSpacing: CGFloat? = nil
@State private var justified: Justified = .none
@State private var justified: Bool = false
@State private var horizontalAlignment: HAlignment = .leading
@State private var verticalAlignment: VAlignment = .top
@State private var distributeItemsEvenly: Bool = false
Expand Down Expand Up @@ -75,7 +75,7 @@ struct ContentView: View {
stepper("Line", $lineSpacing)
}
Section(header: Text("Extras")) {
picker($justified, style: .inline)
Toggle("Justified", isOn: $justified)
Toggle("Distibute evenly", isOn: $distributeItemsEvenly.animation())
}
}
Expand Down Expand Up @@ -134,7 +134,7 @@ struct ContentView: View {
verticalAlignment: verticalAlignment.value,
horizontalSpacing: itemSpacing,
verticalSpacing: lineSpacing,
justification: justified.justification,
justified: justified,
distributeItemsEvenly: distributeItemsEvenly
)
)
Expand All @@ -145,7 +145,7 @@ struct ContentView: View {
verticalAlignment: verticalAlignment.value,
horizontalSpacing: lineSpacing,
verticalSpacing: itemSpacing,
justification: justified.justification,
justified: justified,
distributeItemsEvenly: distributeItemsEvenly
)
)
Expand All @@ -160,24 +160,6 @@ enum Contents: String, CustomStringConvertible, CaseIterable {
var description: String { rawValue }
}

enum Justified: String, CustomStringConvertible, CaseIterable {
case none = "no justification"
case stretchItems = "stretch items"
case stretchSpaces = "stretch spaces"
case stretchItemsAndSpaces = "stretch both"

var description: String { rawValue }

var justification: Justification? {
switch self {
case .none: nil
case .stretchItems: .stretchItems
case .stretchSpaces: .stretchSpaces
case .stretchItemsAndSpaces: .stretchItemsAndSpaces
}
}
}

#Preview {
ContentView()
}
2 changes: 1 addition & 1 deletion Sources/Flow/Internal/LineBreaking.swift
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ func sizes(of items: IndexedLineBreakingInput, availableSpace: CGFloat) -> SizeC
return nil
}
// Calculate total size
var totalSizeOfItems = items.sum(of: \.element.size.lowerBound) + items.dropFirst().sum(of: \.element.spacing)
let totalSizeOfItems = items.sum(of: \.element.size.lowerBound) + items.dropFirst().sum(of: \.element.spacing)
if totalSizeOfItems > availableSpace {
return nil
}
Expand Down
4 changes: 2 additions & 2 deletions Sources/Flow/Support.swift
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ public struct LineBreak: View {

extension View {
/// Allows flow layout elements to be started on new lines, allowing precise control over line breaking.
public func startInNewLine() -> some View {
layoutValue(key: ShouldStartInNewLineLayoutValueKey.self, value: true)
public func startInNewLine(_ enabled: Bool = true) -> some View {
layoutValue(key: ShouldStartInNewLineLayoutValueKey.self, value: enabled)
}

/// Allows modifying the flexibility behavior of views so that flow can layout them accordingly.
Expand Down

0 comments on commit 860e93e

Please sign in to comment.