Skip to content

A GridView that lets items be 'lazily-processed' before being displayed

License

Notifications You must be signed in to change notification settings

Thisura98/swiftui-lazy-gridview

Repository files navigation

SwiftUILazyGridView

CI Status Version License Platform

Create a Grid View that allows items to be processed lazily before being displayed. This pod does not use LazyVGrid or LazyHGrid.

Installation

SwiftUILazyGridView is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod 'SwiftUILazyGridView'

Advantages

✅ Data source is maintained by the Grid View's ViewModel, so yo don't have to fiddle with SwiftUI States

✅ Compatible with different orientations

✅ Variables column and item spacing

✅ Supports all iOS versions that are compatible with SwiftUI

Unsupported Features

⏳ Lazy loading of items (only processing is supported) like SwiftUI's LazyVGrid

⏳ Fixed item size with variable columns

Example

1. A grid that has a source data type of Int, but needs to pre-process it before displaying.

struct ContentView: View{

    var viewModel = LazyGridViewModel<Int, String>(UIScreen.main.bounds.width - 10.0, spacing: 0.0)

    init(){
        setupData()
    }

    private func setupData(){
        for i in 0..<100{
            viewModel.addItem(i)
        }
    }

    var body: some View{
        LazyGridView<Int, String>(viewModel) { (input, callback) in

            // Processing closure
            let processedString = String(format: "Number %d", input)
            callback(processedString)

        } _: { (processed) -> AnyView in

            // View Builder closure
            return AnyView(
                Text(processed)
            )

        } _: { (clickedItem) in
            guard let index = viewModel.getAllItems().firstIndex (where: { $0?.id == clickedItem?.id }) else { return }
            print("You clicked the item at index, \(index)")
            self.addRandomItem()
        }

    }

}

2. A grid that has a custom data source type, but needs to pre-process it before displaying.

struct CustomObject{
    var id: Int
    var name: String
}

struct ContentView: View{

    var viewModel = LazyGridViewModel<CustomObject, String>(UIScreen.main.bounds.width - 10.0, spacing: 0.0)

    init(){
        setupData()
    }

    private func setupData(){
        for i in 0..<100{
            let c = CustomObject(id: i, name: "Random Name")
            viewModel.addItem(c)
        }
    }

    var body: some View{
        LazyGridView<Int, String>(viewModel) { (input, callback) in

            // Processing closure
            DispatchQueue.global().async {
                // Simulate long running task
                let randomDelay = arc4random_uniform(10000000)
                usleep(randomDelay)

                // Processing complete!
                callback(input.name)
            }

        } _: { (processed) -> AnyView in

            // View Builder closure
            return AnyView(
                Text(processed)
            )

        } _: { (clickedItem) in
            guard let index = viewModel.getAllItems().firstIndex (where: { $0?.id == clickedItem?.id }) else { return }
            print("You clicked the item at index, \(index)")
            self.addRandomItem()
        }

    }

}

Requirements

  • iOS 13.0+
  • Xcode 11

Author

thisura1998@gmail.com

License

SwiftUILazyGridView is available under the MIT license. See the LICENSE file for more info.

About

A GridView that lets items be 'lazily-processed' before being displayed

Resources

License

Stars

Watchers

Forks

Packages

No packages published