spacenation / swiftui-grid Goto Github PK
View Code? Open in Web Editor NEW:rocket: SwiftUI Grid layout with custom styles
License: MIT License
:rocket: SwiftUI Grid layout with custom styles
License: MIT License
This is a very useful project. 🙌 I use it to show a lot of images in a waterfall grid. However, the API I'm using uses pagination, so I need to load the next page from the API when the user scrolls to the bottom (actually before the bottom). Do you have any plans to add support for infinite grid? Or maybe hooks to enable this use-case?
Implement layout described in #19
Users should be able to do this
import SwiftUIExtensions
instead of this
import SwiftUI
import SwiftUIExtensions
I made a file browser, users can drag and drop files to upload, and then click on a single file to view, but the two methods cannot be used together.
If I use ondrop, I can't click. I don't know what the problem is.
Grid(items) { item in
Card(title: item.title, image: item.image)
.onTapGesture {
print("onTapGesture", item.title)
}
}
.onDrop(of: ["public.file-url"], delegate: self)
Steps to reproduce:
How to pass item in MyDetailUI ?
NavigationLink(destination: MyDetailUI()){
Grid(self.viewModel.items) {
MyRow(item: $0)
.padding(.top,30)
.padding(.horizontal)
}
}.buttonStyle(PlainButtonStyle())
.gridStyle(
StaggeredGridStyle(tracks: 2, axis: .vertical, spacing: 20))
Building the code in iOS 13.4 crashes 100% of the time with the following message:
Undefined symbols for architecture x86_64:
"property wrapper backing initializer of Grid.Grid.(itemsPreferences in _E80F9D962772A65A2700B0A688C6472F) : [Swift.AnyHashable : Grid.GridItemPreferences]", referenced from:
Grid.Grid.init<A, B where A == SwiftUI.ForEach<A1, A1.Element.ID, B1>, A1: Swift.RandomAccessCollection, B1: SwiftUI.View, A1.Element: Swift.Identifiable>(_: A1, item: (A1.Element) -> B1) -> Grid.Grid<SwiftUI.ForEach<A1, A1.Element.ID, B1>> in Grid.o
Grid.Grid.init<A, B, C where A == SwiftUI.ForEach<A1, B1, C1>, A1: Swift.RandomAccessCollection, B1: Swift.Hashable, C1: SwiftUI.View>(_: A1, id: Swift.KeyPath<A1.Element, B1>, item: (A1.Element) -> C1) -> Grid.Grid<SwiftUI.ForEach<A1, B1, C1>> in Grid.o
Grid.Grid.init<A where A == SwiftUI.ForEach<Swift.Range<Swift.Int>, Swift.Int, A1>, A1: SwiftUI.View>(_: Swift.Range<Swift.Int>, item: (Swift.Int) -> A1) -> Grid.Grid<SwiftUI.ForEach<Swift.Range<Swift.Int>, Swift.Int, A1>> in Grid.o
Grid.Grid.init<A, B where A == SwiftUI.TupleView<(A1, B1)>, A1: SwiftUI.View, B1: SwiftUI.View>(content: () -> SwiftUI.TupleView<(A1, B1)>) -> Grid.Grid<SwiftUI.TupleView<(A1, B1)>> in Grid.o
Grid.Grid.init<A, B, C where A == SwiftUI.TupleView<(A1, B1, C1)>, A1: SwiftUI.View, B1: SwiftUI.View, C1: SwiftUI.View>(content: () -> SwiftUI.TupleView<(A1, B1, C1)>) -> Grid.Grid<SwiftUI.TupleView<(A1, B1, C1)>> in Grid.o
Grid.Grid.init<A, B, C, D where A == SwiftUI.TupleView<(A1, B1, C1, D1)>, A1: SwiftUI.View, B1: SwiftUI.View, C1: SwiftUI.View, D1: SwiftUI.View>(content: () -> SwiftUI.TupleView<(A1, B1, C1, D1)>) -> Grid.Grid<SwiftUI.TupleView<(A1, B1, C1, D1)>> in Grid.o
Grid.Grid.init<A, B, C, D, E where A == SwiftUI.TupleView<(A1, B1, C1, D1, E1)>, A1: SwiftUI.View, B1: SwiftUI.View, C1: SwiftUI.View, D1: SwiftUI.View, E1: SwiftUI.View>(content: () -> SwiftUI.TupleView<(A1, B1, C1, D1, E1)>) -> Grid.Grid<SwiftUI.TupleView<(A1, B1, C1, D1, E1)>> in Grid.o
...
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
If you remove the @State
from @State private var itemsPreferences
here
and the whole .onPreferenceChange
viewmodifier, so lines 17-26 here
this issue goes away.
Bound preference GridPreferencesKey tried to update multiple times per frame.
Debug message on grid init when grid is inside of ScrollView.
I'd like to achieve a layout similar to Google Keep, is something like this possible? (Screenshot)
App sometimes crashes on randomizing values in BuilderView
Image and text rendered in the grid view
Grid(viewModel.items){ item in NavigationLink(destination: BookDetail(displayData: item)){ SearchBookCell(displayData: item) } } .gridStyle( ModularGridStyle(columns: 2, rows: .fixed(200)) ).animation(.easeInOut)
Grid {
...
}
.frame(width: 40)
Fixing this will make #98 possible
I want to autolayout a grid of squares where the width is calculated and the height is the same, ideally something that allowed for any aspect ratio like
ModularGridStyle(columns: .min(135), rows: .aspectRatio(1))
That possible with the current Tracks
? If not, what would you suggest as the best way to add it?
Users would be able to init Grid with ForEach
Grid {
ForEach(0...100, id: \.self) { _ in
Rectangle()
.foregroundColor(.random)
.frame(height: 20)
}
}
The initializer for GridPreferences.Item
is not public so it is impossible to implement custom styles.
If I wrap in my own custom vertical scrollview, then the content does not align to the top left
CustomScrollView {
Grid(0..<1) { idx in
Rectangle()
}
}.gridStyle(ModularGridStyle(columns: .fixed(100), rows: .fixed(100), spacing: 4))
Here link on CustomScrollView: https://github.com/MikhailGorobets/CustomScrollView/blob/master/CustomScrollView.swift
I want to show, with Grid, media from Photos Library
, but I have this result.
The code is.
//ContentView File
import SwiftUI
import Photos
import Grid
struct ContentView: View {
@State private var assetsStruct = [AssetStruct]()
var body: some View {
NavigationView {
ScrollView {
Grid(assetsStruct) { assetStruct in
NavigationLink(destination: Text(assetStruct.asset.localIdentifier)) {
MediaThumbView(asset: assetStruct.asset)
}
}
}
.onAppear {
self.assetsStruct = FetchMediaUtility().fetchNumLastAssetsStruct(numAssets: 20)
}
.gridStyle(
ModularGridStyle(columns: .min(100), rows: .fixed(100))
)
.navigationBarTitle("Media from Photos Library", displayMode: .inline)
}
.navigationViewStyle(StackNavigationViewStyle())
}
}
struct MediaThumbView: View {
let asset:PHAsset
var body: some View {
let manager = PHImageManager.default()
let requestOptions = PHImageRequestOptions()
requestOptions.isSynchronous = true
requestOptions.isNetworkAccessAllowed = true
var thumbnail = UIImage()
manager.requestImage(for: asset, targetSize: CGSize(width: 100, height: 100), contentMode: .aspectFit, options: requestOptions, resultHandler: {(result, info)->Void in
if let result = result {
print("Video o Image width: \(result.size.width) - height: \(result.size.height)")
thumbnail = result
}
})
return Image(uiImage: thumbnail).resizable().aspectRatio(contentMode: .fit)
}
}
//File FetchMediaUtility
import Photos
struct AssetStruct: Identifiable {
let id = UUID()
let asset:PHAsset
}
class FetchMediaUtility {
// Ultimi numAssets di AssetStruct
func fetchNumLastAssetsStruct(numAssets:Int) -> [AssetStruct] {
let fetchOptions = PHFetchOptions()
fetchOptions.fetchLimit = numAssets
fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
let fetchAssets = PHAsset.fetchAssets(with: fetchOptions)
var phAssetStructArray = [AssetStruct]()
for index in 0..<fetchAssets.count {
let asset = fetchAssets.object(at: index)
phAssetStructArray.append(AssetStruct(asset: asset))
}
return phAssetStructArray
}
}
Is there something wrong in my code or something on the Grid?
I hope someone will let me know how to make Grid work, because it is the only repositary that solves my problem.
Implement style structs to modify appearance and interaction.
.gridStyle(SingleColumnGridStyle())
It should be possible to specify tracks with different sizes.
/// CSS
grid-template-columns: 200px 1fr 3fr;
grid-template-rows: 1fr 1fr 1fr;
/// Swift
ModularGridStyle(columns: .template(.fixed(200), .fr(1), .fr(3)), rows: 3)
It'd be very useful to have the ability to split the content into sections with a header view each much like the sections in UICollectionView.
Probably the easiest way would be to add items into the VStack that take up the full width but that probably takes some refactoring of the rowCount
method.
Right now I don't have much time at hand but if nobody picks this up I might work on a PR some time next week.
Related to #18
I just don't know if SDWebImageSwiftUI causes this issue.
Grid(self.store.state.myPostsState.posts) { index in
RoundedURLImage(imageURL: postImageURL(uid: index.reference.documentID), borderWidth: 0)
.scaledToFit()
.cornerRadius(18)
.clipped()
}
.animation(.easeInOut)
Users should be able to import this library as a whole or as separate products
import SwiftUIExtensions
...
import Grid
import Sliders
import Shapes
import Chart
Grid areas is definitely a big feature and it's not going to be included in 1.0.0.
However I would like to start this issue and discussion about it.
Please let me know if you have any thoughts on this and how this can be implemented
Our goal is to have something similar to this.
Grid {
Rectangle()
.gridArea(column: 1, row: 1)
Text("...")
.gridArea(column: 2, row: .span(3))
}
.gridStyle(
ModularGridStyle(columns: 3, rows: 3)
)
Allow users to init Grid with function builder
Grid {
Text("Item")
Text("Item2")
}
How do more data, or how to control scroll.
I have a large grid of NSImageView
's that play animated GIFs. This is very resource intensive, so I would like to pause playing the GIF animation for items that are outside the viewport. It would be useful if Grid could somehow expose this information.
While trying to figure out self sizing dimensions I tried to use .min(0)
. It caused a division by zero that crashed the app.
Consider avoiding the division or doing a fatalError suggesting the correct approach.
Hello everyone,
And sorry for the dumb question: How do I use this package in my app? I have Xcode 11.1 and opened the GridExamples/GridExamples.xcodeproj file. I get several errors and I cannot run any of the examples. Particularly, I want to check the iOS one. These are the errors:
Showing Recent Issues
No account for team "Z8L4G5WZR3". (Add a new account in the Accounts preference pane or verify that your accounts have valid credentials.)
If I want to use this extension, how do I include it in my project?
I know this is so silly, but I am working on my first projects with Swiftui and I don't have much experience with Github, so please be gentle... :)
Thanks in advance!
Hello,
First of all thank you for this library.
I have 2 Grids in my app, the items on the first grid displays a second grid. This grids have different cell styles, when I go back from the second grid to the first one the style of the first one have changed, now it have the style of the second grid...
This behaviour does not exists on the previous version.
Why now on the same package there are things I am not using? Charts, Sliders and other stuff, make more sense have it separated in different packages.
Thanks for your reply.
How difficult would it be to make this library be able to scroll both vertically and horizontally at the same time? I think this functionality would bring the library to another level at least for my application. Would this be overly difficult to accomplish? I would contribute to that if you think it seems doable/desirable feature @ay42
Seems there's a compiler crash in the latest Swift 5.2 compiler.
I haven't yet tracked down exactly what the issue is, but it can be reproduced with simple code like:
import SwiftUI
import Grid
struct Foo: Hashable {}
struct GifsView: View {
var body: some View {
List([Foo()], id: \.self) { _ in
Text("")
}
.gridStyle(ModularGridStyle(columns: 1, rows: 1))
}
}
So it's definitely something in .gridStyle
or GridStyle
.
You can also reproduce the crash by opening the Xcode project in this repo, selecting the "GridDemo macOS" target and and then selecting the "Product => Archive" menu item.
I would recommend getting this project added to https://github.com/apple/swift-source-compat-suite
This issue tracks item rearranging in grid layouts
Identifiable
I tried GridDemo iOS, the StaggeredGridStyle
layout collapses in case the number of grid items is less than the number of tracks.
struct StaggeredGridView: View {
@State var showSettings: Bool = false
@State var style = StaggeredGridStyle(.vertical, tracks: .count(2), spacing: 1)
@State var items: [Int] = (1...69).map { $0 }
These are screenshots of layout collapse.
👍 3 items | 🤔 2 items |
---|---|
Lookin for a good way to pull down when the Grid is in top position to refresh.
Make Grid ZStack based instead of HStack of VStacks
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.