【问题标题】:Problem combining a draggable NSView with SwiftUI components将可拖动的 NSView 与 SwiftUI 组件结合使用时出现问题
【发布时间】:2019-11-14 19:49:14
【问题描述】:

我有一个使用 Cocoa 编写的 NSView 类:

import Cocoa
import SwiftUI

final class EntityViewImpl: NSViewRepresentable {

    func makeNSView(context: NSViewRepresentableContext<EntityViewImpl>) -> EntityView {
        return EntityView(frame: NSRect(x: 0, y: 0, width: 100, height: 200))
    }

    func updateNSView(_ nsView: EntityView, context: NSViewRepresentableContext<EntityViewImpl>) {
        // do nothing
    }
}

class EntityView: NSView {

    var oldMousePosition: NSPoint = .zero
    var oldFrameOrigin: NSPoint = .zero

    override func draw(_ dirtyRect: NSRect) {
        super.draw(dirtyRect)

        NSColor.white.setFill()
        dirtyRect.fill()
    }

    override func mouseDown(with event: NSEvent) {
        self.oldFrameOrigin = self.frame.origin
        self.oldMousePosition = event.locationInWindow
    }

    override func mouseDragged(with event: NSEvent) {
        let pointInSuperview = event.locationInWindow
        self.frame.origin = NSPoint(x: oldFrameOrigin.x + (pointInSuperview.x - oldMousePosition.x),
                                    y: oldFrameOrigin.y + (pointInSuperview.y - oldMousePosition.y))
    }
}

我想在 SwiftUI 视图体中使用此类:

struct ContentView: View {

    var body: some View {
        Group {
            EntityViewImpl()
                .frame(width: 100, height: 100)
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
    }

}

这很好用,我也可以在EntityView 周围拖动。但是,我只能在它的原始框架内“抓住”它。如果我将它拖到边界之外,鼠标事件将不再在原始框架之外的视图部分触发。我是否必须以某种方式“告诉” NSView 移动的 ContentView?

【问题讨论】:

    标签: swift macos swiftui nsview


    【解决方案1】:

    其实如果你使用的是SwiftUI,你需要移动EntityView的superview,像这样:

    override func mouseDown(with event: NSEvent) {
        self.oldFrameOrigin = self.superview!.frame.origin
        self.oldMousePosition = self.superview!.convert(event.locationInWindow, from: self)
    }
    
    override func mouseDragged(with event: NSEvent) {
        let pointInSuperview = self.superview!.convert(event.locationInWindow, from: self)
        self.superview!.frame.origin = NSPoint(x: oldFrameOrigin.x + (pointInSuperview.x - oldMousePosition.x),
                                    y: oldFrameOrigin.y + (-pointInSuperview.y + oldMousePosition.y))
    }
    

    【讨论】:

      猜你喜欢
      • 2019-06-02
      • 2010-11-18
      • 2022-12-21
      • 2015-12-03
      • 1970-01-01
      • 1970-01-01
      • 2022-11-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多