Find, clean, and free up space from large files! Slean lets you sort your gallery by size and efficiently manage your photos and videos with smart filtering and bulk delete options.

I'm pretty new to Swift and SwiftUI. I'm making my first app for sorting a gallery with some extra features.

I was using my own iPhone for testing and just started testing my app on other Apple products.

Everything works fine on iPad Air M1, iPhone 15 Pro, iPhone 15 Pro Max, iPhone 13, iPhone XS (Simulator), and iPhone 11 Pro (Simulator). However, when I tried to show my app to a family member with an iPhone 11, I came across an issue.

Issue Description:

My app takes all photos from iPhone's native gallery, then you can sort it by some spesific filters and delete pictures. It just looks like the native gallery. (I can add photos later if needed) You can just scroll the gallery by swiping up and down. You can press the select button and start selecting pictures to delete.

I recently added a drag-to-select-multiple-pictures feature. This makes it feel more like the native iOS experience, eliminating the need to tap each picture individually.

However, on the iPhone 11, the moment you open the app, you can't scroll. Scrolling is completely locked. You can still select pictures by tapping or dragging, so it's not a touch area issue. The same issue persists on the iPhone 11 simulator.

And I think I found the problematic part in my (sadly messy) ContentView.swift file;

    ScrollView {
        RefreshControl(coordinateSpace: .named("refresh")) {
            await viewModel.refreshMediaItems()
        }
        LazyVGrid(columns: gridColumns, spacing: UIDevice.current.userInterfaceIdiom == .pad ? 12 : 4) {
            let items = viewModel.filteredItems(typeFilter: mediaTypeFilter, specialFilter: specialFilter)
            ForEach(Array(zip(items.indices, items)), id: \.1.id) { index, item in
                MediaThumbnailView(
                    item: item,
                    isSelected: selectedItems.contains(item.id),
                    viewModel: viewModel,
                    onLongPress: {
                        if !isSelectionMode {
                            toggleSelectionMode()
                            selectedItems.insert(item.id)
                        }
                    },
                    onTap: {
                        if isSelectionMode {
                            toggleSelection(item: item)
                        } else {
                            viewModel.selectItem(item)
                        }
                    }
                )
                .aspectRatio(1, contentMode: .fit)
                .background(
                    GeometryReader { geometry in
                        let frame = geometry.frame(in: .named("grid"))
                        Color.clear.preference(
                            key: ItemBoundsPreferenceKey.self,
                            value: [ItemBounds(id: item.id, bounds: frame, index: index)]
                        )
                    }
                )
            }
        }
        .padding(.horizontal, 2)
        .coordinateSpace(name: "grid")
        .onPreferenceChange(ItemBoundsPreferenceKey.self) { bounds in
            itemBounds = Dictionary(uniqueKeysWithValues: bounds.map { ($0.id, $0) })
            itemIndices = Dictionary(uniqueKeysWithValues: bounds.map { ($0.id, $0.index) })
        }
        .gesture(
            DragGesture(minimumDistance: 0)
                .onChanged { gesture in
                    if isSelectionMode {
                        let location = gesture.location
                        if !isDragging {
                            startDragging(at: location, in: itemBounds)
                        }
                        updateSelection(at: location, in: itemBounds)
                    }
                }
                .onEnded { _ in
                    endDragging()
                }
        )
    }
    .coordinateSpace(name: "refresh")
}

you can see the .gesture(.... part. I realised that this DragGesture and ScrollView blocks each other (somehow only on iPhone 11)

highPriorityGesture also won't work.

When I change it with simultaneousGesture, scroll starts to work again.

BUT - since it's simultaneous, when multiple selection mode is activated, when I'm dragging my finger gallery also starts to scroll and it becomes a very unpleasant experience. After this issue I realised on native gallery iOS locks scroll when you are dragging for multiple selection and just when you release your finger you can scroll again even if the multiple selection mode is active. I tried a million things, asked claude, chatgpt etc. etc.

Found some similar issues on stackoverflow but they were all related to iOS 18, not spesific to an iPhone. My app works fine on iOS 18 (15 Pro Max)

iOS 18 drag gesture blocks scrollview

Here are the some of the things I've tried: using highPriorityGesture and simultenousgesture together, tried to lock the scroll briefly while dragging, implement much complicated versions of these things with the help of claude, try to check if isSelectionMode is true or not

All of them broke other things/won't work.

Probably there's something pretty simple that I'm just missing; but iPhone 11 being the single problematic device confuses me. I don't want to mess too much with my already fragile logic.

Find, clean, and free up space from large files! Slean lets you sort your gallery by size and efficiently manage your photos and videos with smart filtering and bulk delete options.
 
 
Q