尝试使用 SwiftUI 制作可滑动的图像视图时,索引意外更改
Posted
技术标签:
【中文标题】尝试使用 SwiftUI 制作可滑动的图像视图时,索引意外更改【英文标题】:Index unexpectedly changes when trying to make Swipeable Image View with SwiftUI 【发布时间】:2021-08-11 11:35:19 【问题描述】:我正在尝试使用 SwiftUI 制作可滑动的图像视图。 向左/向右滑动可将图像向左/向右移动,当您滑动足够长的时间时,图像会滑开并出现下一张/上一张图像:就像主屏幕选项卡一样。 点击左/右使上一张/下一张图像替换当前图像,但没有动画。
此视图获取图像数组、索引和图像偏移量。
其他一些视图检测到滑动手势并更改索引。 问题是,当滑动手势更改索引和图像幻灯片时,索引在动画开始后立即更改,而不是在动画完成后更改。
看来var currentIndex = index
是这个bug的根源,bug如何修复?
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))
【问题讨论】:
【参考方案1】:我使用 Timer 在动画持续时间(=0.5 秒)后更改索引,这解决了问题。而且不需要过渡。
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
ZStack
MyImageView(array: imgArray, index: index-2).offset(x: -screenSize.width, y: 0)
MyImageView(array: imgArray, index: index-1)
MyImageView(array: imgArray, index: index).offset(x: screenSize.width, y: 0)
.offset(dragOffset)
.onAppear(perform: nextindex = index )
.onChange(of: index, perform: value in
if dragOffset.width != 0
dragOffset = .zero
)
.animation(.linear(duration: (dragOffset.width==0) ? 0 : 0.5))
【讨论】:
以上是关于尝试使用 SwiftUI 制作可滑动的图像视图时,索引意外更改的主要内容,如果未能解决你的问题,请参考以下文章
SwiftUI: 使用 ImagePaint 制作边框和填充