DragGesture 在改编简单示例后挂起 SwiftUI

问题描述 投票:0回答:2

我开始在 SwiftUI 中使用 DragGestures。我从一个简单的互联网示例开始,做了一些修改,一切正常。这是代码:

struct DragTest: View {
  @State var viewState = CGSize.zero

  var body: some View {
    RoundedRectangle(cornerRadius: 30)
      .fill(Color.blue)
      .frame(width: 300, height: 400 + viewState.height)
      .offset(x:0, y: viewState.height / 2)
      .gesture(
        DragGesture().onChanged { value in
          viewState = value.translation
        }
          .onEnded { value in
            withAnimation(.spring()) {
              viewState = .zero
            }
          }
      )
  }
}

但是,如果我将框架高度调整更改为减去 viewstate.height 而不是添加,则代码将挂在预览中或处理器使用率 100% 的模拟器中。这看起来像是某种更新循环。

struct DragTest: View {
  @State var viewState = CGSize.zero

  var body: some View {
    RoundedRectangle(cornerRadius: 30)
      .fill(Color.blue)
      .frame(width: 300, height: 400 - viewState.height)
      .offset(x:0, y: viewState.height / 2)
      .gesture(
        DragGesture().onChanged { value in
          viewState = value.translation
        }
          .onEnded { value in
            withAnimation(.spring()) {
              viewState = .zero
            }
          }
      )
  }
}

这是怎么回事?如果我不理解根本原因,我就不会在拖动手势方面走得太远。

swiftui drag
2个回答
1
投票

我想我已经解决了这个问题,尽管解决问题的过程中出现的症状非常令人困惑。看来,如果您打算修改对象的几何形状(

.offset
不会这样做,但
.frame
似乎会这样做),那么您需要在不同的坐标空间中执行
DragGesture
,这不会在
DragGesture
期间更改大小。 (
DragGesture
通常在什么坐标空间中操作?-我不知道,我找到的文档也没有说)。这是有效的代码,另外我尝试了几种变体。

struct DragTest3: View {
  @State var trans = CGSize.zero

  var body: some View {
    Group {
      RoundedRectangle(cornerRadius: 30)
        .fill(Color.blue)
        .frame(width: 300, height: 400 - trans.height)
        .gesture(
          DragGesture(coordinateSpace: .named("outer"))
            .onChanged { value in
              trans = value.translation
            }
        )
    }
    .frame(maxHeight: .infinity)
    .coordinateSpace(name: "outer")
    .border(.black)
  }
}

互联网上最简单的

DragGesture
示例仅使用
.offset
修饰符,因此它们不会崩溃,我无法轻松找到不那么简单的示例。我的理论是,如果发生
DragGesture
的坐标空间正在改变大小,则代码可能会进入死亡螺旋。如果能在某处更详细地描述这些机制,那就太好了。


0
投票

可以确认,我也像安德鲁一样修复了它。就我而言,我必须使用“gesture.location.x”和“gesture.location.y”而不是gesture.translation。


GeometryReader { geometry in
            VStack {
                ZStack {
                   // content...
                }
                .onHover { hovering in
                    isHovered = hovering
                }
                
                Text(name)
                    .foregroundColor(isHovered ? Color.black : Color.black.opacity(0.6))
            }
            .gesture(
                DragGesture(minimumDistance: 0.10, coordinateSpace: .named("outer"))
                .onChanged { gesture in
                    // animation code using gesture.location...
                }
                .onEnded { _ in
                    initialDragOffset = .zero
                }
            )
            
            .onHover { hovering in
                isHovered = hovering
            }
            .animation(Animation.spring(), value: isHovered)
            
            .position(
                x: geometry.size.width * style.left,
                y: geometry.size.height * style.top
            )
            .frame(width: 40, height: 40)
            .coordinateSpace(name: "outer")
        }
    }

© www.soinside.com 2019 - 2024. All rights reserved.