【问题标题】:SwiftUI MagnificationGesture NOT WORKING PROPERLY on MacSwiftUI 放大手势在 Mac 上无法正常工作
【发布时间】:2022-11-12 13:13:22
【问题描述】:

我在 mac 上使用 SwiftUI 中的 MagnificationGesture 有问题。我正在编写一个 Mac 应用程序,我想缩放视图。当我运行该程序时,它可以正常工作几次,然后 onChanged 闭包不再执行。恐怕这是一个错误......(或者我完全误解了什么?)。我最近在 reddit 上发现了一个问题,有人有完全相同的问题:https://www.reddit.com/r/SwiftUI/comments/sd43rk/im_having_an_issue_with_the_magnificationgesture/

我可以在一个非常简单的视图中重现该问题:

struct ContentView: View {
    var body: some View {
        Text("Hello, world!")
            .padding()
            .gesture(MagnificationGesture()
                        .onChanged({ value in
                print(value)
            }))
    }
}

我真的希望,有一个解决方案...

弗雷德里克 :)

【问题讨论】:

  • 你用触控板放大吗?显然,当您碰到触控板的边缘时,放大会停止。但总的来说,它对我来说很好......而且你必须直接在 TextView 上启动手势,这可能很棘手。带有.contentShape(Rectangle()) 的较大框架可以提供帮助。
  • 我用触控板放大。我最初在更大的视图中遇到了这个问题,所以我肯定是在视图上做手势。你试过多少次放大?在我身上它可能在捏 15 次左右后停止......

标签: macos swiftui magnification


【解决方案1】:

这是我稍微改编的代码——对我来说它工作正常,在 30 次之后也是如此(macOS 12.2beta,Xcode 13.2.1)

struct ContentView: View {
    
    @State private var scale: CGFloat = 1
    
    var body: some View {
        Text("Hello, world!")
            .scaleEffect(scale)
            .padding()
            .frame(width: 400, height: 400)
            .contentShape(Rectangle())
            .gesture(MagnificationGesture()
                        .onChanged({ value in
                scale = value
                print(value)
            }))
    }
}

【讨论】:

  • 嗯,我试过了,起初它似乎有效。但后来我注意到,当我缩小几次时,它又停止工作了。而且我确信我击中了手势区域。我目前使用 macOS 12.1、Xcode 13.2.1
  • 我会在另一台设备上试试这个。也许有什么东西被打破了只有一面......
  • 我让一个朋友在他的电脑上用你的代码试试这个,他实际上可以重现这个问题。它并不总是很快发生,但它最终确实发生了。
  • 这令人不安......让我也检查另一台设备
  • 我现在在第三台设备上尝试了它,虽然放大和缩小需要更长的时间,但我也可以在那里重现该问题。 MagnificationGesture 只是在某个时候停止工作......
【解决方案2】:

我不小心找到了一个修复程序。我正在听拖动和放大。拖动更改图像的 x/y 偏移。当放大停止响应时,稍微拖动图像将使放大再次起作用。因此,在每个放大事件结束时,我在偏移量中添加了一个像素。似乎工作。

Image(nsImage: nsImage)
    .resizable()
    .frame(width: width, height: height)
    .scaleEffect(finalAmount + currentAmount)
    .offset(x: offsetX, y:offsetY)
    .onAppear(){
        width = nsImage.width
        height = nsImage.height
    }.gesture(
        DragGesture()
            .onChanged { value in
                offsetY = value.translation.height + offsetYBuffer
                offsetX =  value.translation.width + offsetXBuffer
            }
            .onEnded { value in
                offsetXBuffer = value.translation.width + offsetXBuffer
                offsetYBuffer = value.translation.height + offsetYBuffer
            }
    ).gesture(
        MagnificationGesture()
            .onChanged { value in
                 currentAmount = value - 1
             }
             .onEnded { value in
                 finalAmount += currentAmount
                 currentAmount = 0
                 offsetY += 1 //this seems to fix it
             }
    )

【讨论】: