diff --git a/.swiftpm/xcode/xcshareddata/xcschemes/WrappingStack.xcscheme b/.swiftpm/xcode/xcshareddata/xcschemes/WrappingStack.xcscheme
new file mode 100644
index 0000000..b693472
--- /dev/null
+++ b/.swiftpm/xcode/xcshareddata/xcschemes/WrappingStack.xcscheme
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/Resources/wrapping-hstack-macos.png b/Docs/Resources/wrapping-hstack-macos.png
new file mode 100644
index 0000000..85eadcd
Binary files /dev/null and b/Docs/Resources/wrapping-hstack-macos.png differ
diff --git a/Readme.md b/Readme.md
index 2958531..102b354 100644
--- a/Readme.md
+++ b/Readme.md
@@ -1,7 +1,67 @@
-# Swiftui WrappingStack
+# SwiftUI WrappingStack
-![Swift 5.3](https://img.shields.io/badge/Swift-5.3-FA5B2C) ![Xcode 12.5](https://img.shields.io/badge/Xcode-12-44B3F6) ![iOS 9.0](https://img.shields.io/badge/iOS-8.0-178DF6) ![iPadOS 9.0](https://img.shields.io/badge/iPadOS-8.0-178DF6) ![MacOS 10.10](https://img.shields.io/badge/MacOS-10.10-178DF6) [![Build & Test](https://github.com/diniska/swiftui-wrapping-stack/actions/workflows/test.yml/badge.svg)](https://github.com/diniska/swiftui-wrapping-stack/actions/workflows/test.yml)
+![Swift 5.3](https://img.shields.io/badge/Swift-5.3-FA5B2C) ![Xcode 12.5](https://img.shields.io/badge/Xcode-12.5-44B3F6) ![iOS 9.0](https://img.shields.io/badge/iOS-9.0-178DF6) ![iPadOS 9.0](https://img.shields.io/badge/iPadOS-9.0-178DF6) ![MacOS 10.10](https://img.shields.io/badge/MacOS-10.10-178DF6) [![Build & Test](https://github.com/diniska/swiftui-wrapping-stack/actions/workflows/test.yml/badge.svg)](https://github.com/diniska/swiftui-wrapping-stack/actions/workflows/test.yml)
A SwiftUI Views for wrapping HStack elements into multiple lines.
-`WrappingHStack` - provides `HStack` that supports line wrapping
+## List of supported views
+
+* `WrappingHStack` - provides `HStack` that supports line wrapping
+
+## How to use
+### Step 1
+Add a dependency using Swift Package Manager to your project: [https://github.com/diniska/swiftui-wrapping-stack](https://github.com/diniska/swiftui-wrapping-stack)
+
+### Step 2
+Import the dependency
+
+```swift
+import WrappingStack
+```
+
+### Step 3
+Replace `HStack` with `WrappingHStack` in your view structure. It is compatible with `ForEach`.
+
+```swift
+struct MyView: View {
+
+ let elements = ["Cat 🐱", "Dog 🐶", "Sun 🌞", "Moon 🌕", "Tree 🌳"]
+
+ var body: some View {
+ WrappingHStack(id: \.self) { // use the same id is in the `ForEach` below
+ ForEach(elements, id: \.self) { element in
+ Text(element)
+ .padding()
+ .background(Color.gray)
+ .cornerRadius(6)
+ }
+ }
+ .frame(width: 300) // limiting the width for demo purpose. This line is not needed in real code
+ }
+
+}
+```
+
+The result of the code above:
+
+![WrappingHStack for macOS](./Docs/Resources/wrapping-hstack-macos.png)
+
+
+## Customization
+
+Customize appearance using the next parameters. All the default SwiftUI modifiers can be applied as well.
+
+### `WrappingHStack` parameters
+
+Parameter name | Description
+---------------|--------------
+`alignment` | horizontal and vertical alignment. `.center` is used by default. Vertical alignment is applied to every row
+`horizontalSpacing` | horizontal spacing between elements
+`verticalSpacing` | vertical spacing between the lines
+
+## Performance considerations
+
+The code written in a way to cache the elements representing views sizes, it doesn't re-calculate the size for different views with the same id.
+
+* huge numbers of elements are not recommended, although the same applies to `HStack` where `LazyHStack` is a better alternative for the long rows. If you have a large number of elements - double-check the memory and performance on a real device
+* it is pretty good in terms of CPU consumption as every element calculates its size only once.
diff --git a/Sources/WrappingStack/WrappingHStack.swift b/Sources/WrappingStack/WrappingHStack.swift
index 6c5416b..a3690a5 100644
--- a/Sources/WrappingStack/WrappingHStack.swift
+++ b/Sources/WrappingStack/WrappingHStack.swift
@@ -32,13 +32,21 @@ public struct WrappingHStack,
alignment: Alignment = .center,
horizontalSpacing: CGFloat = 0,
verticalSpacing: CGFloat = 0,
@ViewBuilder content create: () -> ForEach
- ){
+ ) {
let forEach = create()
data = forEach.data
content = forEach.content
@@ -111,8 +119,24 @@ public struct WrappingHStack ForEach) {
- self.init(id: \.id, content: create)
+ /// Creates a new WrappingHStack
+ ///
+ /// - Parameters:
+ /// - alignment: horizontal and vertical alignment. Vertical alignment is applied to every row
+ /// - horizontalSpacing: horizontal spacing between elements
+ /// - verticalSpacing: vertical spacing between the lines
+ /// - create: a method that creates an array of elements
+ public init(
+ alignment: Alignment = .center,
+ horizontalSpacing: CGFloat = 0,
+ verticalSpacing: CGFloat = 0,
+ @ViewBuilder content create: () -> ForEach
+ ) {
+ self.init(id: \.id,
+ alignment: alignment,
+ horizontalSpacing: horizontalSpacing,
+ verticalSpacing: verticalSpacing,
+ content: create)
}
}
@@ -121,15 +145,21 @@ extension WrappingHStack where ID == Data.Element.ID, Data.Element: Identifiable
@available(iOS 14, macOS 11, *)
struct WrappingHStack_Previews: PreviewProvider {
static var previews: some View {
- WrappingHStack(id: \.self, alignment: .topLeading) {
- ForEach(["Hello1", "world1", "Hello2", "world2", "Hello3", "world3", "Hello4", "world4 ", "Hello1"], id: \.self) { item in
- Text(item)
+ WrappingHStack(
+ id: \.self,
+ horizontalSpacing: 8,
+ verticalSpacing: 8
+ ) {
+ ForEach(["Cat 🐱", "Dog 🐶", "Sun 🌞", "Moon 🌕", "Tree 🌳"], id: \.self) { element in
+ Text(element)
.padding()
- .background(Color(.systemGray))
- .cornerRadius(3)
+ .background(Color.gray.opacity(0.1))
+ .cornerRadius(6)
}
}
+ .padding()
.frame(width: 300)
+ .background(Color.white)
}
}