简体   繁体   English

Mac Catalyst - 向 UITableView/UIScrollView 添加单击 + 拖动手势

[英]Mac Catalyst - Adding Click + Drag gesture to UITableView/UIScrollView

I am in the process of enabling Catalyst support for a freelancing project — one of the things that I noticed right away is the differing behaviour of scrolling views on MacOS vs iOS.我正在为一个自由职业项目启用 Catalyst 支持——我立即注意到的一件事是 MacOS 和 iOS 上滚动视图的不同行为。 I expected to be able to click and drag UIScrollView s or UITableView s as I would normally in the iOS Simulator, but I am only able to scroll these views using the mouse's scroll wheel (or two finger gesture on a trackpad).我希望能够像通常在 iOS 模拟器中一样单击并拖动UIScrollViewUITableView ,但我只能使用鼠标的滚轮(或触控板上的两个手指手势)滚动这些视图。

Is there any way I can mimic the UIPanGestureRecognizer behaviour on iOS for a UIScrollView or UITableView using a Click + Drag gesture on MacOS?有没有什么方法可以模仿 iOS 上的UIScrollViewUITableViewUIPanGestureRecognizer行为,在 MacOS 上使用 Click + Drag 手势?

Thank you :)谢谢 :)

如果Private API是可以接受的,那么 Mac Catalyst 14.0 中的新 API 正是这样做的:

- [UIScrollView _setSupportsPointerDragScrolling:]

I noted the same for UICollectionViews.我注意到 UICollectionViews 也是如此。 I decided to use scroll buttons and have them set the selection, and offsets.我决定使用滚动按钮并让它们设置选择和偏移量。 You can do the same with UIGestureRecognizers in each cell and then set the offsets, etc of the parent UITableView or UICollectionView.您可以对每个单元格中的 UIGestureRecognizers 执行相同的操作,然后设置父 UITableView 或 UICollectionView 的偏移量等。 I've not thought about simple UIScrollViews.我没有想过简单的 UIScrollViews。

The following will do the trick:以下将解决问题:

First a convenience extension:首先是一个方便的扩展:

public extension CGPoint {
    static func - (a: CGPoint, b: CGPoint) -> CGPoint {
        return CGPoint(x: a.x-b.x, y: a.y-b.y)
    }
}

Add a pan gesture to the scroll view:向滚动视图添加平移手势:

scrollView.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(onPan(_:))))

And finally the selector:最后是选择器:

private var s0: CGPoint = .zero
@objc func onPan(_ gesture: UIPanGestureRecognizer) {
    let ds: CGPoint = gesture.translation(in: scrollView)
    switch gesture.state {
        case .began:
            s0 = scrollView.contentOffset
        case .changed:
            scrollView.contentOffset = CGPoint(x: 0, y: max(0, min(scrollView.contentSize.height-scrollView.height, (s0-ds).y)))
        default: break
    }
}

(Full set of CGPoint convenience methods included here: https://github.com/aepryus/Acheron ) (此处包含全套 CGPoint 便捷方法: https ://github.com/aeryus/Acheron)

值得注意的是,从 Monterey 开始,如果您在触控板上使用两个手指手势,那么它的工作原理就像在设备上滚动一样——包括弹跳。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM