Framer Classic » Flow component » Tips and tricks

Tips and tricks

A few tips and an example of how to implement the iOS Swipe Back interaction using Edge Swipe.

Setting the first screen

I think you’ve seen these two friends before:

flow = new FlowComponent
flow.showNext screenA

They seem to be inseparable.

  • The first line creates a FlowComponent instance …
  • … and the second one adds the first screen.

But you can create a FlowComponent and add a screen in one go:

flow = new FlowComponent screenA

Setting size, position, and background color

By default, a FlowComponent will assume the size of the Screen, but you can give it a desired size and position with the common, well-known properties.

flow = new FlowComponent
    width: Screen.width
    height: Screen.height - 40
    y: 20

A FlowComponent’s background color is what you see when you overdrag (so you’ll only see it on scrollable screens). It’s "black" by default, but easy to change:

flow = new FlowComponent
    backgroundColor: "red"

Several other properties, for instance borderRadius, will also work.

You can set properties and a start screen at the same time, if you first set the screen (screenA below), followed by a , and then add the other properties.

# A FlowComponent with a first screen, and extra properties
flow = new FlowComponent screenA,
    width: Screen.width
    height: Screen.height - 40
    y: 20
    backgroundColor: "red"
    borderRadius: 20
Open in Framer

(It’s a bit like when creating an animation object: first the layer followed by a comma, and then the other properties.)

Setting a custom size, position, and background color

Using Edge Swipe events to create the iOS Swipe Back gesture

We have the FlowComponent, with its iOS-inspired showNext() transition, and Framer has Edge swipe events. So I wanted to see if we can combine them to create the iOS Swipe Back interaction.

It’s doable, but I had to use onEdgeSwipeLeftStart, and onEdgeSwipeLeft, and onEdgeSwipeLeftEnd to have it work as it should.

The iOS Swipe Back interaction
Open in Framer

A bunch of things are happening here:

1. The user started swiping from the left edge

Event: Screen.onEdgeSwipeLeftStart

When the user starts swiping, I flag it by setting a weAreSwiping variable to yes.

This will impede taps from triggering a showNext() when we’re in this ‘edge swiping from the left’ mode. Because otherwise, the FlowComponent would advance to the next screen the moment the user lifts his finger.

# User started swiping from the left edge …
Screen.onEdgeSwipeLeftStart ->
    # … so now taps shouldn’t trigger anything
    weAreSwiping = yes

2. The user is swiping along happily

Event: Screen.onEdgeSwipeLeft

When the user is busy swiping we let the current screen follow the movement (by updating its x with the current event.offset).

But we only want to do this when not on the start screen, so we first check the length of our flow.stack.

# We continuously adjust the x position of the “current” screen
# and of the “previous” screen underneath
Screen.onEdgeSwipeLeft ->

    # only when not the first screen
    if flow.stack.length > 1

        # Current screen
        flow.current.x = event.offset.x

        # Previous screen, will be hidden at first
        flow.previous.visible = yes

        # … and only moves at half the speed
        flow.previous.x = (event.offset.x/2) - (flow.previous.width/2)

We also move the previous screen at half the speed. We first make it visible, though, because any screen not currently in use will be hidden.

3. The user stopped swiping

Event: Screen.onEdgeSwipeLeftEnd

When the user has finished swiping, we take a look at the current event.offset.x.

If it’s less than Screen.midX, the user did not pan halfway so we should animate back. The current screen’s x is set back to 0 with a spring animation (the same as in the transition). And we do the same with previous but place it half its width more to the left.

# End of the swipe gesture
Screen.onEdgeSwipeLeftEnd ->
    # only when not the first screen
    if flow.stack.length > 1
        # Panned less than half the screen width?
        # -> animate back to the initial position
        if event.offset.x < Screen.midX

            flow.current.animate
                x: 0
                options:
                    curve: "spring(300, 35)"

            flow.previous.animate
                x: - (flow.previous.width / 2)
                options:
                    curve: "spring(300, 35)"
        # Panned more than half the screen?
        # -> Trigger transition
        else
            flow.showPrevious()
    # Taps are allowed to happen again
    Utils.delay 0.1, ->
        weAreSwiping = no

But when the user did swipe far enough, we trigger showPrevious() to have the transition run until the end.

4. Ready again for tapping action

Taps are allowed to trigger transitions again, so we set weAreSwiping back to no. But only after a (minimal) 🛠 Delay, to not have it sneak in a quick showNext().

    # Taps are allowed to happen again
    Utils.delay 0.1, ->
        weAreSwiping = no

By the way, this is how that weAreSwiping variable is used to impede taps:

# Tap on A ? -> Show screen B
Screen_A.onTap ->
    if not weAreSwiping
        flow.showNext Screen_B
Open in Framer

In every onTap event handler, we first check weAreSwiping before doing a showNext().


Leave a Reply