Horizontal Scrollview inside a Vertical Scrollview

I’m having a Horizontal Scrollview (verticalScrollDisabled=true) inside a Vertical Scrollview.
When I am scrolling vertically inside the Horizontal Scrollview I want the outer Scrollview to get scrolled vertically.
Now if I want to scroll the outer scrollview I need to do it outside the Horizontal Scrollview.
Is there any way to get it done?

1 Like

I have a vertical scroll view with one horizontal scroll view per “row”. To handle scrolling I have an overlay for each horizontal scroll view. When this overlay is moved in x direction (over a threshold distance) the specific horizontal scroll view’s touch logic is called. If the overlay is moved in y direction the vertical scroll view’s touch logic is called.

2 Likes

Yes I have a plugin for this on the old marketplace. I think it solves the problem you mention. Here’s a demo video of it

3 Likes

@diongeorge Okay getting it on the public Solar directory today. I’ll post here when it works :slight_smile:

@diongeorge https://github.com/solar2d/io.joehinkle-plugin.embeddablescrollview

you can find the source here. It seems using it as a plugin isn’t working just yet though. If you want to use it now, just copy the lua files into your directory.

Edit: the plugin works now. Just add it to the build.settings

1 Like

Hey @joecoronasdk,
I’m facing a bug.

I have a horizontal scrollview inside the vertical scrollview.
After adding your source code, I can scroll vertically inside the horizontal scrollview and the parent scroll moves.
Although when I do so and tap on the parent scrollview again, the screen re-adjusts to the position where the horizontal scrollview object was.

I have an animation that starts when parent scrollview crosses a particular position, but that too isn’t triggered if I scrolled vertically while pressing on the horizontal scrollview’s object.

Any idea what I’m doing wrong?

Here’s the code.
The main file:

local ChildObject = require("..");
.
.
.
local scrollView = {
    x = centerX,
    y = centerY,
    width = screen_width,
    height = screen_height,
    horizontalScrollDisabled = true,
    hideScrollBar = true,
    hideBackground = true,
    friction = 0.972,
    isBounceEnabled = false,
    listener = scrollListener
}

local a = ChildObject.new(scrollview)

scrollView:insert(a);

In ChildObject

local M = {};
local EmbeddableScrollview = require('lib.embeddable_scrollview'); // Your source code is added here.

function M.new(parentScollView)

local scrollView = EmbeddableScrollview.create({
    width = CW * 0.85,
    height = stoneFrameHeight,
    horizontalScrollDisabled = false,
    verticalScrollDisabled = false,
    hideScrollBar = true,
    hideBackground = true,
    isBounceEnabled = false,
    friction = 0.972,
    displayObjectToGiveTouchFocusFromVerticalScroll = parentScollView
  });

return scrollview;
end
return M;

I’m not sure I understand the problem, maybe you could make a video showing the weird behavior?

Also, I think removing verticalScrollDisabled = false, from the child would help. Try changing it to verticalScrollDisabled = true,

1 Like

@joecoronasdk Changing the verticalScrollDisabled = true solved the first half of the issues. Thanks a lot!

Currently the parent vertical scrollview is having a listener which doesn’t get triggered when I’m scrolling vertically inside the horizontal scrollview. Any idea what could be wrong?

If a video showing this bug would help, do let me know.

2 Likes

I don’t think a video would help with that bug, because I think the problem is that the “hack” that happens in the plugin is that the embedded scrollview just passes its touch events to the parent one. That may involve it skipping over those touch events.

I don’t have time to jump into the code and work on it. But you can look through its implementation and make a pull request if you find a way to repair those callbacks. https://github.com/joehinkle11/SolarEmbeddableScrollview

Edit: I just realized the repo was private. It’s public now

I am not sure what EmbeddableScrollview = require('lib.embeddable_scrollview') does, but you can just add a horizontal scrollView into the vertical scrollView.

Control the scrolling using focus (read here). E.g. if y has moved more than 10, then give focus to the vertical-scrollview. If x has moved more than 10, then give focus to the horizontal-scrollview.

Then control the touch-through by returning true or false.

local phase = event.phase

    if ( phase == "moved" ) then
        local dy = math.abs( ( event.y - event.yStart ) )
        -- If the touch on the button has moved more than 10 pixels,
        -- pass focus back to the scroll view so it can continue scrolling
        if ( dy > 10 ) then
            scrollView:takeFocus( event )
        end
    end
2 Likes

Thanks @yosu