0

How do I stop a scrollView when the user lifts their fingers instead of just bouncing back to the top?

var displayData = UITextView()

func displayTallTable() {

    displayData.text = outputString
    
    // getFrameBounds (x, y, width, height)
    displayData.frame = CGRect(x: x, y: y, width: w, height: h)
    
    self.addSubview(scrollView)
    scrollView.addSubview(displayData)

    let g = self.safeAreaLayoutGuide
    
    scrollView.leadingAnchor.constraint(equalTo: g.leadingAnchor).isActive = true
    scrollView.trailingAnchor.constraint(equalTo: g.trailingAnchor).isActive = true
    scrollView.topAnchor.constraint(equalTo: g.topAnchor).isActive = true
    scrollView.bottomAnchor.constraint(equalTo: g.bottomAnchor).isActive = true        
}

I can drag the view up but when I lift my fingers, it just bounces back to the top.

So, I added UIScrollViewDelegate to the class:
class TallView: UIView, UIScrollViewDelegate { ... }

and have tried the following, none of which is called:

func scrollViewWillBeginDecelerating(_ scrollView: UIScrollView) {
    debugPrint("scrollViewWillBeginDecelerating")
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
    debugPrint("scrollViewDidScroll")
}
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
    debugPrint("scrollViewWillBeginDragging")
}
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
    debugPrint("scrollViewWillEndDragging")
}
func scrollViewDidChangeAdjustedContentInset(_ scrollView: UIScrollView) {
    debugPrint("scrollViewDidChangeAdjustedContentInset")
}

It seems that :

func killScroll() {
    self.scrollView.isScrollEnabled = false;
    self.scrollView.isScrollEnabled = true;
}

(from: How can I programmatically force-stop scrolling in a UIScrollView?) should do the trick, but I don't know what should be calling it.

What am I missing?

Greg
  • 667
  • 8
  • 19

1 Answers1

0

If I understand you correctly, you may want this this effect:

func scrollViewDidScroll(_ scrollView: UIScrollView) {
        if !scrollView.isTracking {
            let contentOffset = scrollView.contentOffset
            // if you want to locate to the top, you could set: let contentOffset = CGPoint.zero
            scrollView.setContentOffset(contentOffset, animated: false)
        }
    }
}
Dharman
  • 30,962
  • 25
  • 85
  • 135
leorider
  • 186
  • 5
  • I have that function above (without the contents) but it is never called. What would cause it to be called? – Greg Oct 17 '20 at 21:25
  • Have you set delegete like this: scrollView.delegate = self – leorider Oct 17 '20 at 21:38
  • Yes, I tried that both inside ````override func draw(_ rect: CGRect) ```` and inside ````func displayTallTable()```` – Greg Oct 17 '20 at 21:59
  • I saw your code: `scrollView.addSubview(displayData)`, but `displayData` is UITextView's object, that is an another scrollview. may be it is `displayData` that disable your scrollView's gesture, after all, `displayData` has its own gesture. – leorider Oct 17 '20 at 22:18
  • Sounds like I have the wrong approach? I originally created the UITextView then discovered it could be much longer than the screen height (especially when I landscape), so I put inside the scrollView. Is there a better, or correct, way to accomplish this? – Greg Oct 17 '20 at 22:38
  • I am sorry, I am not sure I understand your question. But it is better not to put `UITextView` inside `UIScrollView `, as they are both `UIScrollView `. – leorider Oct 17 '20 at 23:29
  • Well, that is actually part of a solution. How would I force the UITextView to stop scrolling when fingers are removed from the screen? – Greg Oct 18 '20 at 02:29
  • If your scrollView delegate could be called, my code in answer can stop ti – leorider Oct 18 '20 at 08:09
  • Ok, I'm learning something and feel like I'm getting somewhere! I've removed the scrollView to leave just the textView ````displayData````, replaced ````class TallView: UIView, UIScrollViewDelegate { ... }```` with ````class TallView: UIView, UITextViewDelegate { ... }````, and replaced ````scrollView.delegate```` with ````displayData.delegate = self````. But I am still stumped on what function will get called when scroll and release... – Greg Oct 18 '20 at 16:53
  • 1
    when you scroll `displayData `, `scrollViewDidScroll ` will be called, when your finger is on the screen, `scrollView.isTracking` is true, when your finger is lifted, `scrollView.isTracking` is false – leorider Oct 19 '20 at 01:04