Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lag when loading images #2

Open
ltns35 opened this issue Jun 26, 2023 · 5 comments
Open

Lag when loading images #2

ltns35 opened this issue Jun 26, 2023 · 5 comments

Comments

@ltns35
Copy link

ltns35 commented Jun 26, 2023

Displaying more than 10 images in a grid and start dragging it produces lag and animation issues.

@gadirom
Copy link
Owner

gadirom commented Jun 26, 2023

@ltns35 Can you put here some minimal code that reproduces the issue?

@ltns35
Copy link
Author

ltns35 commented Jun 26, 2023

The complete source code is a little bit complex, but what I'm doing is loading images from photosPicker and display them after being processed as UIImage.

ReordableVGrid(items: $vm.selectedItems,
                       activeItem: $mediaReorder,
                       maxItems: maxSelectionCount,
                       columns: gridColumns,
                       alignment: .center,
                       spacing: spacing,
                       moveAnimation: moveAnimation,
                       selectAnimation: selectAnimation,
                       reorderDelay: 0.3,
                       id: \.self,
                       addButton: EmptyView()) {
           ForEach {
                // Display images
           }
}
.photosPicker(isPresented: $pickerShown,
                      selection: $vm.selectedItems,
                      maxSelectionCount: maxSelectionCount,
                      matching: .images,
                      photoLibrary: .shared())

@gadirom
Copy link
Owner

gadirom commented Jun 26, 2023

From what I could guess from your code, it seems that the refreshing of the views in the grid that happen during the dragging triggers some expensive image loading operations. It would be easier for me to try to look into that if I had some minimal working code example that reproduces the issue.
As a test try for example displaying already loaded images with Image() and see if the lagging goes.

@ltns35
Copy link
Author

ltns35 commented Jun 26, 2023

I think I found the issue, I've made the following test and I perceived the problem is related to the ScrollView, when I add it it's when the lag appears, if no ScrollView is present the dragging is smooth.

import SwiftUI
import PhotosUI
import ReordableViews

struct DemoView: View {

    private let moveAnimation: Animation = .spring(response: 0.5, dampingFraction: 0.7, blendDuration: 0)
    private let selectAnimation: Animation = .spring(response: 0.1, dampingFraction: 0.7, blendDuration: 0)

    @State
    private var images: [UIImage] = []

    @State
    private var selectedItems: [PhotosPickerItem] = []

    @State
    private var currentDraggedItem: UIImage? = nil

    @State
    private var pickerVisible = false

    var body: some View {
        ScrollView {
            VStack {
                Button("Select images") {
                    pickerVisible = true
                }

                ReordableVGrid(items: $images,
                               activeItem: $currentDraggedItem,
                               maxItems: 20,
                               columns: [.flexible(), .flexible(), .flexible()],
                               alignment: .center,
                               spacing: 20,
                               moveAnimation: moveAnimation,
                               selectAnimation: selectAnimation,
                               reorderDelay: 0.3,
                               id: \.self,
                               addButton: EmptyView()) { item,_,_,_,_,_,_ in
                    Image(uiImage: item.wrappedValue)
                        .resizable()
                        .width(.infinity)
                        .aspectRatio(1, contentMode: .fit)
                } orderChanged: { _,_ in
                }
            }
            .photosPicker(isPresented: $pickerVisible,
                          selection: $selectedItems,
                          maxSelectionCount: 20,
                          matching: .images,
                          photoLibrary: .shared())
            .onChange(of: selectedItems) { items in
                images.removeAll()

                items.forEach { item in
                    Task {
                        if let data = try? await item.loadTransferable(type: Data.self) {
                            if let image = UIImage(data: data) {
                                images.append(image)
                            }
                        }
                    }
                }
            }
        }
    }
}

@gadirom
Copy link
Owner

gadirom commented Jun 26, 2023

Ha! I never thought to test it with a ScrollView, just because I didn’t know how to handle the scrolling. Turns out it somehow messes with the algorithm. My guess is it’s forcing GeometryReader to run too frequently.

Any way, I will try to look into this issue, but I’m not too optimistic.

For now my advice is to avoid ScrollView.

When I thought of using this package in a real application I had an idea to make several pages, but I never solved the problem of drugging an element outside the grid to place it to another page. So I opted for a UIKit solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants