如何在swiftUI 2.0中解决onEnd手势中不需要的偏移

如何在swiftUI 2.0中解决onEnd手势中不需要的偏移,swiftui,Swiftui,我有这个代码用于在scrollview中滑动行,在第一次尝试时效果很好,但是在一些滚动和滑动之后,它开始为偏移量提供一些值,甚至几乎为零,并且它使红色背景显示在边缘!我知道,你们中的一些人可能会使用填充解决方案,它会起作用并覆盖不需要的红色背景,但即使使用这种不令人信服的解决方案,文本也会与其他文本发生偏移!我认为这是SwiftUI的一个bug,否则我很高兴知道正确的答案。谢谢 这是因为即使您尝试垂直滚动,并且水平过渡应用于偏移,也会处理拖动手势。因此,解决方案是添加某种边界条件,只检测水平阻

我有这个代码用于在scrollview中滑动行,在第一次尝试时效果很好,但是在一些滚动和滑动之后,它开始为偏移量提供一些值,甚至几乎为零,并且它使红色背景显示在边缘!我知道,你们中的一些人可能会使用填充解决方案,它会起作用并覆盖不需要的红色背景,但即使使用这种不令人信服的解决方案,文本也会与其他文本发生偏移!我认为这是SwiftUI的一个bug,否则我很高兴知道正确的答案。谢谢


这是因为即使您尝试垂直滚动,并且水平过渡应用于偏移,也会处理拖动手势。因此,解决方案是添加某种边界条件,只检测水平阻力

这里只是一个简单的演示(您可以考虑更精确的演示)。使用Xcode 12/iOS 14进行测试,足以进行演示

DragGesture()
.onChanged({ (value) in
    // make offset only when some limit exceeds or when it definitely sure
    // that you drag in horizontal only direction, below is just demo
    if (abs(value.translation.height) < abs(value.translation.width)) {
        Items[i].offset = value.translation.width
    }
})
DragGesture()
.onChanged({(值)在
//仅当某些限制超过或确定时才进行偏移
//只在水平方向拖动,下面只是演示
if(abs(value.translation.height)
更新:忘了我也改为使用索引,以避免以后按id查找,所以下面是更完整的快照

ForEach(Items.indices, id: \.self) { i in
    ZStack
    {
        Rectangle()
            .fill(Color.red)
        HStack
        {
            VStack(alignment: .leading)
            {
                
                Text(Items[i].name)
                    .frame(minWidth: 0, maxWidth: .infinity)
                    .padding()
                    .background(Color.yellow)
                    .offset(x: Items[i].offset)
                    .gesture(
                        DragGesture()
                        .onChanged({ (value) in
                            if (abs(value.translation.height) < abs(value.translation.width)) {
                                Items[i].offset = value.translation.width
                            }
                        })
                        .onEnded({ (value) in
                            Items[i].offset = 0.0
                        }))
                    .animation(.easeInOut)
            }
        }
    }
ForEach(Items.index,id:\.self){i in
焦面
{
矩形()
.填充(颜色.红色)
HStack
{
VStack(对齐:。前导)
{
文本(项目[i].名称)
.frame(最小宽度:0,最大宽度:无穷大)
.padding()
.背景(颜色.黄色)
.offset(x:Items[i].offset)
.手势(
德拉格斯特尔()
.onChanged({(值)在
if(abs(value.translation.height)
这是因为即使您尝试垂直滚动,也会处理拖动手势,并且会对偏移量应用水平过渡。因此,解决方案是添加某种仅检测水平拖动的边界条件

这里只是一个简单的演示(你可以考虑更精确的一个)。使用Xcode 12/iOS 14进行测试就足够演示了

DragGesture()
.onChanged({ (value) in
    // make offset only when some limit exceeds or when it definitely sure
    // that you drag in horizontal only direction, below is just demo
    if (abs(value.translation.height) < abs(value.translation.width)) {
        Items[i].offset = value.translation.width
    }
})
DragGesture()
.onChanged({(值)在
//仅当某些限制超过或确定时才进行偏移
//只在水平方向拖动,下面只是演示
if(abs(value.translation.height)
更新:忘了我也改为使用索引,以避免以后按id查找,所以下面是更完整的快照

ForEach(Items.indices, id: \.self) { i in
    ZStack
    {
        Rectangle()
            .fill(Color.red)
        HStack
        {
            VStack(alignment: .leading)
            {
                
                Text(Items[i].name)
                    .frame(minWidth: 0, maxWidth: .infinity)
                    .padding()
                    .background(Color.yellow)
                    .offset(x: Items[i].offset)
                    .gesture(
                        DragGesture()
                        .onChanged({ (value) in
                            if (abs(value.translation.height) < abs(value.translation.width)) {
                                Items[i].offset = value.translation.width
                            }
                        })
                        .onEnded({ (value) in
                            Items[i].offset = 0.0
                        }))
                    .animation(.easeInOut)
            }
        }
    }
ForEach(Items.index,id:\.self){i in
焦面
{
矩形()
.填充(颜色.红色)
HStack
{
VStack(对齐:。前导)
{
文本(项目[i].名称)
.frame(最小宽度:0,最大宽度:无穷大)
.padding()
.背景(颜色.黄色)
.offset(x:Items[i].offset)
.手势(
德拉格斯特尔()
.onChanged({(值)在
if(abs(value.translation.height)
No,因为它不按轴分隔距离。No,因为它不按轴分隔距离。