tommitomtom
tommitomtom

Reputation: 115

Swift: "Freeze" bouncing in a scrollView

I am trying to work a little bit with scrollViews. So I have a ScrollView on my Controller with bouncing enabled. So now then I scroll the view bounces at the end of the page like I want to.

But now I want to freeze my bouncing. I try to explain it a little bit more:

I scroll up in my ScrollView. The end of the page begins. So now the bouncing begins and its scrolling a little bit up. Then I undrag the scrollView the view bounces back. But I want the scrollView to stay in this position (because I push the view away and it looks weird when its bouncing while I push it).

Things I tried:

1.Set the frame on the scroll view to the current bouncing position. This just edits the frame but still bounces the scrollView.

v2.view.frame = CGRect(x: CGFloat(0), y: CGFloat(CURRENTBOUNCING), width: width, height: height)

2.Turn bounces off. This just ends the current bounce and after you can't bounce anymore. So if I don't want it to bounce back this doesn't work.

scrollView.bounces = false

3.Set contentOffset manually. Changes nothing for me even if I write it after initializing

scrollView.contentOffset.y -= 100 // Or something like this

4.Change the contentSize. This changes nothing I think because of the constraints

scrollView.contentSize = CGSize(width: self.view.frame.width, height: self.view.frame.height - 200)

5.Turn always bouncing vertically off. Same like 2.

scrollView.alwaysBounceVertical = false

6.Paging. I tried this because now I page manually. But then I miss the bouncing into nothing before paging. With paging you can see the next page while scrolling behind the end. But the next page should be loaded after dragging.

Hope someone can help me :)

EDIT

7.Taking a picture of my current scrollview to display it on my screen over the scrollview. This takes an image with an delay and not at the right moment ( so the bounces is at the half then capturing or already done.

let renderer = UIGraphicsImageRenderer(size: scrollView.bounds.size)
pufferImage.image = renderer.image { ctx in
        scrollView.drawHierarchy(in: scrollView.bounds, afterScreenUpdates: true) }

Upvotes: 1

Views: 1733

Answers (2)

Peter Lapisu
Peter Lapisu

Reputation: 21005

I had a similar use case, the key was to switch the contentOffset into contentInset this negated the effect of the bounce back

maybe not a 100% complete solution, but i leave it here for inspiration

case UIGestureRecognizerStateEnded:
    self.interactor.hasStarted = NO;
    if (self.interactor.shouldFinish) {
        UIEdgeInsets ei = self.scrollView.contentInset;
        ei.top -= self.scrollView.contentOffset.y;
        self.scrollView.contentInset = ei;
        [self.interactor finishInteractiveTransition];
    } else {
        [self.interactor cancelInteractiveTransition];
    }
    break;
default:

Upvotes: 0

Markus
Markus

Reputation: 598

Ran into the same problem. The solve is to record the content offset and change the vertical offset of the scrollview to that value while simultaneously turning scrolling off.

private var dismissTriggerd = false
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    if keyPath == "contentOffset" {

        if scrollView.contentOffset.y < -70 && dismissTriggerd == false {
            scrollViewTop.constant = scrollView.contentOffset.y * -1
            scrollView.isScrollEnabled = false
            dismissTriggerd = true
            dismiss(animated: true)
        }
    }
}


deinit {
    scrollView.removeObserver(self, forKeyPath: "contentOffset")
}

Upvotes: 1

Related Questions