平移/滑动手势使用代码滚动文本视图?

pan / swipe gestures to scroll a textview using code?

我在视图控制器上有一个文本视图。 textview 的尺寸很小,因此很难将手指放在那里并向上或向下滚动。

我真正想做的是按住手指并向上拖动,视图向上滚动,向下拖动,视图向下滚动。

我目前正在通过 UISwipeGestureRecognizer(在视图中所以有很多 space)来为每次滑动向上滚动一条线,它是这样的:

func scrollTextUp() {
    let currentOffset = textView.contentOffset
    let padding : CGFloat = 10
    textView.setContentOffset(
        CGPoint(
            x: currentOffset.x,
            y: currentOffset.y - padding < 0 ? 0 : currentOffset.y - padding
        ),
        animated: true
    )
}

我想我需要一个 UIPanGestureRecognizer 来完成这项工作,但我如何检测向上或向下的动作并忽略所有其他方向?

有什么建议吗?

我在这里的建议是使用 touchesMoved 并计算触摸的当前位置与触摸的先前位置之间的差异。然后您可以使用该值来更改内容偏移量。注意:您还需要添加保护措施,防止偏移量变得太小或太大。请参阅下面的快速示例,这是快速完成的,因此可能有更好的方法来完成某些部分,最显着的是确定 textview 的初始偏移量,但这应该让你继续。

class ViewController: UIViewController {
    let tv = UITextView()
    var originalYOffset: CGFloat = 0

    override func viewDidLoad() {
        super.viewDidLoad()
        view.addSubview(tv)
        tv.text = "Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text "
        tv.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        originalYOffset = tv.contentOffset.y
    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        if let touch = touches.first {
            let currentLocation = touch.location(in: touch.view)
            let previousLocation = touch.previousLocation(in: touch.view)
            let amountMoved = previousLocation.y - currentLocation.y
            let newOffset = min(max(originalYOffset, tv.contentOffset.y + amountMoved), tv.contentSize.height - tv.frame.size.height)

            tv.contentOffset.y = newOffset
        }
    }
}