fermoya / SwiftUIPager

Native Pager in SwiftUI
MIT License
1.29k stars 171 forks source link

MagnificationGesture making Pager not scroll #58

Closed rakesh1504 closed 4 years ago

rakesh1504 commented 4 years ago

Hi, I am using your SwiftUIPager. It is looking great. In pageview, I am adding Image. It is working fine. But when I add MagnificationGesture() on Image, scrolling get stopped. And I am not able to scroll anymore. Can you please help me to sort this problem?

fermoya commented 4 years ago

Hi @rakesh1504 ,

Have you tried using simultaneousGesture for your MagnificationGesture? There’s an issue at the moment with SwiftUI, gestures are not well designed and they collide

rakesh1504 commented 4 years ago

Thank you for your immediate response.

Yes, I also tried it with simultaneousGesture, but no luck.

fermoya commented 4 years ago

So the only thing I could suggest is make the pages have some padding some space between each other and use swipeableArea(.allAvailable). Also try to reduce the size of the image inside the container.

UIKit has something that SwiftUI doesn’t offer and is that you can make a gesture fail and not be recognized. Unfortunately, in SwiftUI there isn’t anything similar at the moment, so we’ll have to wait.

rakesh1504 commented 4 years ago

Sure, I will try it. And SwiftUI is still too buggy.

Thank you.

fermoya commented 4 years ago

@rakesh1504 I'm gonna close this as I've done with other issues with this same problem. The reason is, there's nothing that can be done at the moment, SwiftUI has its limitations in its first version. I'll keep an eye on WWDC20 and reopen this or other issue related when the upgrade the framework with more features.

Thanks for feedback

fermoya commented 4 years ago

@rakesh1504 nonetheless, I’d appreciate it if you could share here a small case example. I want to have it as a record, I’m considering some changes.

fermoya commented 4 years ago

@rakesh1504 , maybe this workaround works for you:

    var customGesture: some Gesture {
        LongPressGesture(minimumDuration: 0.2).sequenced(before:
            MagnificationGesture().onChanged { value in
                self.imageScale = value
            }
        )
    }

This way, the MagnificationGesture isn't recognized unless the LongPressureGesture is recognized first, that is, after 0.2s

rakesh1504 commented 4 years ago

I found one more issue. When I am zooming the page, all pages are getting zoomed. Please check this gif. ezgif com-optimize

rakesh1504 commented 4 years ago

` struct ColorsExampleView: View {

@State var pageIndex = 0
@State var scale:CGFloat = 1.0
var colors: [Color] = [
    .red, .blue, .black, .gray, .purple, .green, .orange, .pink, .yellow, .white
]

var body: some View {
    NavigationView {
        GeometryReader { proxy in
            VStack(spacing: 10) {
                Text("Use the controls below to move across the colors")
                    .bold()
                    .padding(10)
                    .foregroundColor(.blue)
                Pager(page: self.$pageIndex,
                      data: self.colors,
                      id: \.self) {
                        self.pageView($0)
                }
                .disableDragging()
                .itemSpacing(10)
                .padding(20)
                .onPageChanged({ page in
                    withAnimation {
                        self.pageIndex = page
                    }
                })
                .frame(width: min(proxy.size.height, proxy.size.width),
                       height: min(proxy.size.height, proxy.size.width))
                .background(Color.gray.opacity(0.3))
                .navigationBarTitle("Color Picker", displayMode: .inline)

                Spacer()

                HStack {
                    Spacer()
                    Circle()
                        .fill(self.colors[self.pageIndex])
                        .frame(width: 80)
                        .overlay(Circle().stroke(self.pageIndex < 4 ? Color.gray.opacity(0.5) : Color.black, lineWidth: 5))
                    Spacer()
                    Text("\(self.colors[self.pageIndex].rgb)")
                    Spacer()
                }

                Spacer()

                HStack {
                    Spacer()
                    Button(action: {
                        withAnimation {
                            self.pageIndex = max(0, self.pageIndex - 1)
                        }
                    }, label: {
                        HStack(spacing: 10) {
                            Image(systemName: "backward.fill")
                                .padding()
                            Text("Previous")
                        }
                    }).disabled(self.pageIndex <= 0)
                    Spacer()
                    Button(action: {
                        withAnimation {
                            self.pageIndex = min(self.colors.count - 1, self.pageIndex + 1)
                        }
                    }, label: {
                        HStack(spacing: 10) {
                            Text("Next")
                            Image(systemName: "forward.fill")
                                .padding()
                        }
                    }).disabled(self.pageIndex >= self.colors.count - 1)
                    Spacer()
                }

                Spacer()
            }
        }
    }
    .navigationViewStyle(StackNavigationViewStyle())
}

func pageView(_ color: Color) -> some View {
    Image("pizza1delivery")
    .resizable()
    .scaledToFit()
    .cornerRadius(5)
    .scaleEffect(self.scale)
    .shadow(radius: 5)
    .gesture(MagnificationGesture()
        .onChanged({ (value) in
            print(value)
            self.scale = value.magnitude
        })
    )
}

}

`

fermoya commented 4 years ago

@rakesh1504 , you're adding the gesture to all pages. Have in mind that the content block doesn't return one page but several pages. You'll need to do something like

@State var currentPage = 0

Page(...) { page in
    MyPage()
        .gesture(page == self.currentPage ? myGesture : nil) // Added just to the current page
}

Could you please open a new issue next time? I feel you're having trouble using SwiftUI and Combine.

rakesh1504 commented 4 years ago

Indeed.

Sure, I will open a new issue next time. Actually I was thinking it works like as UITableView, UICollectionView in swift. But it is totally different.

fermoya commented 4 years ago

I've created a new modifier pagingPriority to choose the best way to embed swipeGesture. If you use pagingPriority(.simultaneous), it'll help you best manage gestures within your custom page.

See v1.7.0 for more info.