Search code examples
luaoverlaycoronasdk

Corona Overlay doesn't show


I had a problem creating a loading scene in between scenes, the solution I got was to use an overlay, I've been trying this for days but for some reason I can't get it to work. I have two scenes, one that shows a list of items, and another that shows a page of text based on which row was clicked. The problem now is the first scene, that shows the list, downloads images to display and of course this takes a while so whenever i transition into that screen, the app appears to be frozen while everything loads up.

I've found out that it does actually go into the overlay scene, since the print statements i put in it print out, but it just doesn't display anything and when i removed the code that hides the overlay after, it still appears to hang, it goes into the overlay scene, doesn't display anything and then renders the table before finally displaying the overlay so instead of showing an overlay, having everything load up beneath, and then hiding the overlay, it appears to be frozen in the current scene, loads up everything beneath, shows overlay and then hides overlay right after.

My code for the three scenes are below, the one I'm posting now is the only one that actually worked once and then never again, it showed the overlay while everything loaded like I wanted but for some reason, it never worked again after that one time. I'm getting really frustrated with it and no forum has given me a solution, I'd really really appreciate some help. Thanks!

ItemListPage.lua

local composer = require ( "composer" )
local widget = require( "widget" )
local json = require( "json" )

-- Load the relevant LuaSocket modules
local http = require( "socket.http" )
local ltn12 = require( "ltn12" )

local scene = composer.newScene()


--NavigationBar elements initiated
--Removed for readability


--image handler
local function networkListener( event )
    if ( event.isError ) then
        print ( "Network error - download failed" )
    end

    print ( "event.response.fullPath: ", event.response.fullPath )
    print ( "event.response.filename: ", event.response.filename )
    print ( "event.response.baseDirectory: ", event.response.baseDirectory )
end


local function onRowRender( event )

    -- Get reference to the row group
    local row = event.row
    local params=event.row.params
    local itemRow=3;

    -- Cache the row "contentWidth" and "contentHeight" because the row bounds can change as children objects are added
    local rowHeight = row.contentHeight
    local rowWidth = row.contentWidth

    row.rowTitle = display.newText( row, params.topic, 0, 0, nil, 14 )
    row.rowTitle:setFillColor( 0 )
    row.rowTitle.anchorX = 0
    row.rowTitle.x = 0
    row.rowTitle.y = (rowHeight/2) * 0.5

    --Other elements removed for readabilty (it's all just text objects)

    --Download Image
    --params referring to items[i]
    local imagelink =params.imagelink

    -- Create local file for saving data
    local path = system.pathForFile( params.imagename, system.TemporaryDirectory )
    myFile = io.open( path, "w+b" ) 

    -- Request remote file and save data to local file
    http.request{
        url = imagelink, 
        sink = ltn12.sink.file( myFile )
    }

    row.Image = display.newImageRect(row, params.imagename, system.TemporaryDirectory, 25, 25)
    row.Image.x = 20
    row.Image.y = (rowHeight/2) * 1.5

    row:insert( row.rowTitle )
    row:insert( row.Image )
end

local function onRowTouch( event )
    local row = event.target
    local params=event.target.params

    composer.removeScene(composer.getSceneName("current"))
composer.gotoScene( "itempage" , {params=params})

end


function scene:create( event )
    local sceneGroup = self.view

end

function scene:show( event )
    local sceneGroup = self.view
    local phase = event.phase

    if phase == "will" then
        -- Called when the scene is still off screen and is about to move on screen
        --overlay
        composer.showOverlay( "loading", { isModal = true })

    elseif phase == "did" then

        --Table stuff
        local scrollBarOptions = {
            sheet = scrollBarSheet,  -- Reference to the image sheet
            topFrame = 1,            -- Number of the "top" frame
            middleFrame = 2,         -- Number of the "middle" frame
            bottomFrame = 3          -- Number of the "bottom" frame
        }
        -- Table
        local tableView = widget.newTableView(
            {
                left = 0,
                top = navBar.height,
                height = display.contentHeight-navBar.height,
                width = display.contentWidth,
                onRowRender = onRowRender,
                onRowTouch = onRowTouch,
                listener = scrollListener
            }
        )

        --json work
        local filename = system.pathForFile( "items.json", system.ResourceDirectory )
        local decoded, pos, msg = json.decodeFile( filename )

        if not decoded then
            print( "Decode failed at "..tostring(pos)..": "..tostring(msg) )
        else
            print( "File successfully decoded!" )
        end
        local items=decoded.items

        -- create a white background to fill screen
        local background = display.newRect( display.contentCenterX, display.contentCenterY, display.contentWidth, display.contentHeight )
        background:setFillColor( 1 )    -- white
        sceneGroup:insert( background )

        -- Insert rows
        for i = 1, #items do
            -- Insert a row into the tableView
            print( "Adding a row!" )
            tableView:insertRow{
                rowHeight = 100,
                rowColor = { default={ 0.8, 0.8, 0.8, 0.8 } },
                lineColor = { 1, 0, 0 },
                params=items[i]
            }
        end

        sceneGroup:insert( tableView )

        composer.hideOverlay( "fade", 100 )
    end 
end

-- other functions and elements unused and removed for readability

loading.lua

local composer = require ( "composer" )
local widget = require( "widget" )
local json = require( "json" )
local scene = composer.newScene()

-- Create the widget
function scene:create( event )
    local sceneGroup = self.view
    local background = display.newRect( display.contentCenterX, display.contentCenterY, display.contentWidth, display.contentHeight )
    background:setFillColor( 1 )    -- white

    local text = display.newText( "Loading scene", 0, 0, nil, 14 )
    text:setFillColor( 0 )
    text.anchorX = display.contentCenterX
    text.x = display.contentCenterX
    text.y = display.contentCenterY

    sceneGroup:insert( background )
    sceneGroup:insert( text )
    print ( "In loading create")

end


function scene:show( event )
    local sceneGroup = self.view
    local phase = event.phase

    if phase == "will" then

    elseif phase == "did" then

        print ( "In loading show")
    end 
end

-- other functions and elements unused and removed for readability

ItemDisplayPage.lua

local composer = require ( "composer" )
local widget = require( "widget" )
local json = require( "json" )
local scene = composer.newScene()


--NavigationBar elements initiated
--This creates the "back button", when clicked it returns to the previous scene, in this case "itemListPage"
--it takes, no parameters
local function handleLeftButton( event )
   if ( event.phase == "ended" ) then
        composer.removeScene(composer.getSceneName("current"))
    composer.gotoScene(composer.getSceneName("previous"))
   end
   return true
end
--Remaining navbar elements removed for readability

function scene:create( event )
local sceneGroup = self.view
local params=event.params

-- create a white background to fill screen
local background = display.newRect( display.contentCenterX, display.contentCenterY, display.contentWidth, display.contentHeight )
background:setFillColor( 1 )    -- white

--creating header bar
local bar = display.newRect( navBar.height + (headerBarHeight*0.5), display.contentCenterY, display.contentWidth, headerBarHeight )
bar:setFillColor( 1 )

-- create stuff
local title = display.newText(params.topic, 0, 0, nil, 14 )
title:setFillColor( 0 )
title.anchorX = 0
title.x = margin
title.y = ((2*headerBarHeight/2) * 0.5)+navBar.height

local Image = display.newImageRect(params.imagename, system.TemporaryDirectory, 25, 25)
Image.x = 50
Image.y = display.contentCenterY


-- all objects must be added to group (e.g. self.view)
sceneGroup:insert( background )
sceneGroup:insert( title )
sceneGroup:insert( Image)

end
-- other functions and elements unused and removed for readability

Solution

  • I suggest you do not use scene.show event for loading.

    Use timer.performWithDelay to load all data:

    --in scene:show
    elseif phase == "did" then
      timer.performWithDelay(0, function()
        local scrollBarOptions = {
        --put your code here
        composer.hideOverlay( "fade", 100 )
      end)
    

    Your current code didn't show overlay because engine waits for scene:show event before rendering anything. So rendering of overlay and images occured after all images are loaded.

    In my code timer.performWithDelay doesn't block scene:show execution, so you will see overlay rendered before loading images