I am trying to make Swipeable Image View with SwiftUI. Swiping left/right moves image left/right, and when you swipe long enough, the image slides away and next/previous image will appear: Just like home screen tabs. Tapping left/right makes previous/next image replace the current image, but without animation.
This view gets array of images, index and image offset.
Some other view detects swipe gesture and changes index. The problem is, when swipe gesture changes index and image slides, the index changed right after animation started, not after animation is complete.
It seems like var currentIndex = index is the origin of this bug, bug how can I fix it?
struct MyImagesView: View {
@Binding var index:Int
let imgArray:[URL]
@Binding var dragOffset:CGSize
@State var nextindex:Int = 1
@State var screenSize:CGRect = UIScreen.main.bounds
var body: some View {
var currentindex = index
let insertionAnimation: ()->AnyTransition = { nextindex > currentindex ? AnyTransition.move(edge: .leading) : AnyTransition.move(edge: .trailing) }
let removalAnimation: ()->AnyTransition = { nextindex < currentindex ? AnyTransition.move(edge: .trailing) : AnyTransition.move(edge: .leading) }
ZStack {`enter code here`
MyImageView(array: imgArray,index:currentindex-2).offset(x: -screenSize.width, y: 0)
MyImageView(array: imgArray,index:currentindex-1)
MyImageView(array: imgArray,index:currentindex).offset(x: screenSize.width, y: 0)
}
.offset(dragOffset)
.onAppear(perform: { nextindex = index })
.onChange(of: index, perform: { value in
if dragOffset.width != 0 && value != currentindex {
nextindex = value
Timer.scheduledTimer(withTimeInterval: 0.5, repeats: false, block: { _ in dragOffset = .zero; currentindex = value })
dragOffset.width = nextindex>currentindex ? -screenSize.width : (nextindex < currentindex ? screenSize.width : 0)
}
})
.transition(.asymmetric(insertion: insertionAnimation(), removal: removalAnimation()))
.animation(.linear(duration: (dragOffset.width==0) ? 0 : 0.5))
}
}