PageView
PageView copied to clipboard
Page snapping not working
I may have misunderstood what's happening here, but hopefully a video demo will help show what the issue is. Essentially when I swipe on a page, I can see the next page, but when I stop swiping the pages just stay in the half-transitioned state instead of snapping to either the new or current page based on the threshold.
import PageView
import SwiftUI
public struct ImageCarouselView: View {
let imageURLs: [URL]
@State private var index: Int = 0
public var body: some View {
HPageView(selectedPage: $index, data: imageURLs) { imageURL in
CachedImage(imageURL) // Kingfisher image view
// Text(imageURL.absoluteString) // Same problem
}
}
}
// For the purposes of demonstration code
extension URL: Identifiable {
var id: String { absoluteString }
}
ImageCarouselView(imageURLs: imageURLs)
.frame(width: width, height: width * 4 / 3)
As far as I can tell from the docs this should work as-is. I've tried passing each of the different pageGestureType
s to the constructor, and also tried some extreme settings for pageSwitchThreshold
(0.1 and 0.9), but neither of these seems to have any effect.
I thought that there could be some issue with an interactor above this component in the view hierarchy, but there's nothing obvious that stands out to me, and I'm not quite sure what to look for. This view originally had an onTapGesture
handler on it, but I removed that to narrow down the problem.
Here's a video of the issue. It's from the simulator for ease of recording, but the same behaviour happens on a real device.
https://user-images.githubusercontent.com/202400/138448200-131f5301-4195-4678-85a7-d31b493e4353.mov
iOS: 14.5, Xcode: 13.0. PageView: 1.5.0
Happy to provide any more information that may help diagnose this!
Hi, sorry for the delay. Unfortunately I cannot reproduce the issue. The simple demos from Examples/
work as expected on iOS 14.2 and iOS 15.2 (which are very similar to your simple case), compiled using Xcode 12.3/13.2 Could you provide simple project with the issue along with xcode/simulator version? Meanwhile I'm gonna try it on iOS 14.5, maybe it's happening only on specific OS versions.
EDIT: On iOS 14.5, Xcode 13.2 page snapping works fine
Hi, I ran into the same issue.
I figured out the reason. It seems pretty bizarre that this happens.
I removed all @EnvironmentObject
and private
properties in the class or view struct and moved the PageView object into a new struct view. This resolved my issue.
Hope this helps.
@pradeep-spikey-tech Hmmm, could you provide example View
that causes that? Also what version of Xcode and iOS are you running?
@fredyshox Below is an example, I had created a page view with this format which caused the issue.
Only @EnvironmentObject var
, let
and private let
properties cause issues, not @State private var
or private var
.
import PageView
struct UI_View: View {
@EnvironmentObject var controller: Controller
private let theme = PageControlTheme(
backgroundColor: .clear,
dotActiveColor: Color("someColor"),
dotInactiveColor: .gray,
dotSize: 10.0,
spacing: 12.0,
padding: 0.0,
// xOffset: 8.0,
// yOffset: -8.0,
xOffset: 0.0,
yOffset: 0.0,
alignment: Alignment(horizontal: .center, vertical: .bottom)
)
var body: some View {
HPageView(selectedPage: $selectedPage, data: 0..<3, theme: theme) { index in
RoundedRectangle()
.frame(minHeight: 180, maxHeight: 220, alignment: .center)
.aspectRatio(contentMode: ContentMode.fill)
}
}
I moved the HPageView into a separate View Struct and changed the code structure as follows and it worked:
import PageView
struct UI_View: View {
@EnvironmentObject var controller: Controller
private let theme = PageControlTheme(
backgroundColor: .clear,
dotActiveColor: Color("someColor"),
dotInactiveColor: .gray,
dotSize: 10.0,
spacing: 12.0,
padding: 0.0,
// xOffset: 8.0,
// yOffset: -8.0,
xOffset: 0.0,
yOffset: 0.0,
alignment: Alignment(horizontal: .center, vertical: .bottom)
)
var body: some View {
UI_PageView()
}
}
struct UI_PageView: View {
@State private var someStateVariable: SomeStateVariable!
var body: some View {
let theme = PageControlTheme(
backgroundColor: .clear,
dotActiveColor: Color("someColor"),
dotInactiveColor: .gray,
dotSize: 10.0,
spacing: 12.0,
padding: 0.0,
// xOffset: 8.0,
// yOffset: -8.0,
xOffset: 0.0,
yOffset: 0.0,
alignment: Alignment(horizontal: .center, vertical: .bottom)
)
HPageView(selectedPage: $selectedPage, data: 0..<3, theme: theme) { index in
RoundedRectangle()
.frame(minHeight: 180, maxHeight: 220, alignment: .center)
.aspectRatio(contentMode: ContentMode.fill)
}
}
}
It looks as if there was something funky going on with changing the pageIndex
binding.
Although I've tried with data: Range<Int>
, only the first swipe works correctly. After that, every attempt to change the page results the view remaining in the in-between state described by @danpalmer.