Glatteisen
Glatteisen

Reputation: 173

ScrollView - Gesture Recognizer - Swipe vertically

I have a UIScrollView that works when swiping left or right, however I've reduced the size of the scrollView so, now display area doesn't fully occupy the superview's frame, and swiping works only within the frame of the scroll view.

I would like to be able to scroll vertically even when swiping up and down outside the horizontal bounds of the narrowed scroll view.

It was recommended that I use a gesture recognizer, but that's beyond my current familiarity with iOS and could use more specific advice or a bit more guidance to get started with that.

Upvotes: 2

Views: 3637

Answers (3)

9it3e1
9it3e1

Reputation: 398

  1. Search for a component called SwipeGestureRecognizer : enter image description here

  2. Grab it and drop it on top of the View (use the hierarchy to make sure you drop it on it, if you drop it on another element this code will not work):

    enter image description here

  3. Select one of the SwipeGestureRecognizer in the hierarchy and go to its attribute page. Change Swipe to Right.

enter image description here

  1. Make sure the other recogniser has the Swipe attribute to Left

enter image description here

  1. Select UIScrollView and uncheck Scrolling enabled

enter image description here

  1. Connect detectSwipe() (see source code below) to both recognizers.

--

@IBAction func detectSwipe (_ sender: UISwipeGestureRecognizer) {
    if (currentPage < MAX_PAGE && sender.direction == UISwipeGestureRecognizerDirection.left) {
        moveScrollView(direction: 1)
    }
    if (currentPage > MIN_PAGE && sender.direction == UISwipeGestureRecognizerDirection.right) {
        moveScrollView(direction: -1)
    }
}



func moveScrollView(direction: Int) {
    currentPage = currentPage + direction
    let point: CGPoint = CGPoint(x: scrollView.frame.size.width * CGFloat(currentPage), y: 0.0)
    scrollView.setContentOffset(point, animated: true)      

    // Create a animation to increase the actual icon on screen
    UIView.animate(withDuration: 0.4) {
        self.images[self.currentPage].transform = CGAffineTransform.init(scaleX: 1.4, y: 1.4)
        for x in 0 ..< self.images.count {
            if (x != self.currentPage) {
                self.images[x].transform = CGAffineTransform.identity
            }
        }
    }
}    

Refer to https://github.com/alxsnchez/scrollViewSwipeGestureRecognizer for more

Upvotes: 1

Yitzchak
Yitzchak

Reputation: 3416

There is a simpler approach then use a Gesture Recognizer =]

You can setup the superview of the scroll view (which is BIGGER...) to pass the touches to the scroll view. It's working M-A-G-I-C-A-L-Y =]

First, select the view that will pass all it's touches to the scroll view. if your parent view is already ok with that you may use it. otherwise you should consider add a new view in the size that you want that will catch touches.

Now create a new class (I'll use swift for the example)

class TestView: UIView {

    @IBOutlet weak var Scroller: UIScrollView!

    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {

        let view = super.hitTest(point, with: event)

        if (view == self) {
            return Scroller
        }

        return view

    }

}

Nice! now as you can see we added an outlet of the scroller. so use interface builder, select the new view and set it's class to "TestView" in the identity inspector (Or to the name that you'll use for your custom class).

After you set the class and your view is still selected go to connections inspector and connect "Scroller" to your scroll view on the storyboard. All connected properly =]

That's it!! no gesture recognizer needed!! The new view will pass all it's touches to the scroll view and it'll behave just like you pan in it =]

In my answer I used that answer

EDIT: I improved the code now, it wasn't working as expected before, now it catches only when in needs and not every touch in the app as before

Upvotes: 2

Yitzchak
Yitzchak

Reputation: 3416

I don't have time for detailed answer but:

In storyboard drag a pan gesture recognizer on the scroll view's superview... Connect it's action with your view controller and in this action change the scroll view position by using the properties from the gesture recognizer that you got as parameter

Tip: when connecting the action change parameter type from Any to UIPanGestureRecognizer in the combo box

please don't see this answer as recommendation to use this approach in your problem, I don't know if that's the best way, I'm just helping you to try it

Upvotes: 0

Related Questions