Composer firing scene show multiple times on one gotoScene("...") command...help please

Hi,

I have a project to load a series of scenes (composer) and it seems on 3 of my scenes that load newVideo objects, the scene:show is being fired several times and I can’t understand why.

The calling code looks like this:

local btn2 = self:getObjectByTag("button2"); local function btn2\_click(e) if(e.phase == "ended") then composer.gotoScene("video\_paulprice"); end end btn2:addEventListener("touch", btn2\_click);

The composer scene show method looks like this:

function scene:show( e ) local sceneGroup = self.view local phase = e.phase local halfscreenwidth=display.contentWidth/2; local halfscreenheight=display.contentHeight/2 local bg = self:getObjectByTag("backgroundBox"); bg.x= display.contentWidth/2; bg.y= display.contentHeight/2; bg.xScale=0.5; bg.yScale=0.5; print("CM PHASE: " .. e.phase) if (phase == "did") then video = native.newVideo( display.contentCenterX+1, display.contentCenterY-40, 535, 390 ); local function videoListener( event ) print( "Event phase: " .. event.phase ); end video:load( "videos/video\_1.mp4", system.ResourceDirectory ); video:addEventListener( "video", videoListener ); video:play() end local btn1 = self:getObjectByTag("button1"); local function btn1\_click(e) display.remove(video) composer.gotoScene("scene3"); end btn1:addEventListener("tap", btn1\_click); local btn2 = self:getObjectByTag("button2"); local function btn2\_click(e) video:removeSelf() composer.gotoScene("scene4"); end btn2:addEventListener("tap", btn2\_click); end

My terminal, debugger output looks like this:

2014-12-08 10:37:29.756 Corona Simulator[4392:175603] CM PHASE: will 2014-12-08 10:37:29.757 Corona Simulator[4392:175603] CM PHASE: did 2014-12-08 10:37:29.852 Corona Simulator[4392:175603] CM PHASE: will 2014-12-08 10:37:29.852 Corona Simulator[4392:175603] CM PHASE: will 2014-12-08 10:37:29.852 Corona Simulator[4392:175603] CM PHASE: will 2014-12-08 10:37:29.852 Corona Simulator[4392:175603] CM PHASE: will 2014-12-08 10:37:29.852 Corona Simulator[4392:175603] CM PHASE: will 2014-12-08 10:37:29.853 Corona Simulator[4392:175603] CM PHASE: will 2014-12-08 10:37:29.853 Corona Simulator[4392:175603] CM PHASE: will 2014-12-08 10:37:29.885 Corona Simulator[4392:175603] CM PHASE: did 2014-12-08 10:37:29.885 Corona Simulator[4392:175603] CM PHASE: did 2014-12-08 10:37:29.885 Corona Simulator[4392:175603] CM PHASE: did 2014-12-08 10:37:29.885 Corona Simulator[4392:175603] CM PHASE: did 2014-12-08 10:37:29.885 Corona Simulator[4392:175603] CM PHASE: did 2014-12-08 10:37:29.886 Corona Simulator[4392:175603] CM PHASE: did 2014-12-08 10:37:29.886 Corona Simulator[4392:175603] CM PHASE: did

Other scenes in my project the show method is only being fired once. I’m using build: Version 2014.2494 (2014.11.5)

Any help would be hugely helpful!

Thanks

Chris.

Your button listener is missing ‘return true’ at the end.

Can’t see your scene listener declaration, but sometimes developers accidentally listen incorrectly for scene events. What does your scene:addEventListener look like?

Thanks for your reply. I’ve added the return true to the button handler, sadly it doesn’t seem to have made much difference.

My listener declaration looks like this

scene:addEventListener( "create", scene ) scene:addEventListener( "show", scene ) scene:addEventListener( "hide", scene ) scene:addEventListener( "destroy", scene )

These scenes were created using the scene UI software in the latest daily build, it seems if I create them in code alone i don’t see the same issue. 

For this release of the app I’m working on, I will simply re-create all the composer ui created scenes. Strange though!?

Hi @Milner99,

Do you mean that you created these scenes in the Composer GUI visual editor, and it’s behaving differently than if you create these scenes in pure code using the Composer library structure?

Best regards,

Brent

Hi Brent,

You are correct. Hand coded scenes work perfectly. One of the composer GUI scenes works great - the other 3 were causing problems. I ended up hand coding all of them. 

I did copy and paste, then rename and edit the scene files to create the following three that were a problem (first was fine). Could that be the reason? 

Thanks

C

Hey there,

Could you please post a bug report and paste the number back here? You don’t need to include a video, just the project files with one of these GUI created scenes so that i have something to test against?

Thanks in advance,

alex

Case: 37623

Your button listener is missing ‘return true’ at the end.

Can’t see your scene listener declaration, but sometimes developers accidentally listen incorrectly for scene events. What does your scene:addEventListener look like?

Thanks for your reply. I’ve added the return true to the button handler, sadly it doesn’t seem to have made much difference.

My listener declaration looks like this

scene:addEventListener( "create", scene ) scene:addEventListener( "show", scene ) scene:addEventListener( "hide", scene ) scene:addEventListener( "destroy", scene )

These scenes were created using the scene UI software in the latest daily build, it seems if I create them in code alone i don’t see the same issue. 

For this release of the app I’m working on, I will simply re-create all the composer ui created scenes. Strange though!?

Hi @Milner99,

Do you mean that you created these scenes in the Composer GUI visual editor, and it’s behaving differently than if you create these scenes in pure code using the Composer library structure?

Best regards,

Brent

Hi Brent,

You are correct. Hand coded scenes work perfectly. One of the composer GUI scenes works great - the other 3 were causing problems. I ended up hand coding all of them. 

I did copy and paste, then rename and edit the scene files to create the following three that were a problem (first was fine). Could that be the reason? 

Thanks

C

Hey there,

Could you please post a bug report and paste the number back here? You don’t need to include a video, just the project files with one of these GUI created scenes so that i have something to test against?

Thanks in advance,

alex

Case: 37623

I also had this issue, although in my case the problem was in my button widget handler from my menu module. I had forgotten to place my gotoScene command inside of the button’s “ended” phase. So my menu module was actually going to my game scene multiple times from my button handler. 

Old Code:

local function handlePlay(event) composer.gotoScene("game") end

New Code:

local function handlePlay(event) if event.phase == "ended" then composer.gotoScene("game") end end

Hi,

I have the similar issue with multiple times when i back from another scene.

for example:

view1.lua

----------------------------------------------------------------------------------------- -- -- view1.lua -- ----------------------------------------------------------------------------------------- local composer = require( "composer" ) local scene = composer.newScene() local widget = require( "widget" ) local function gotoOknoScene( self, event ) --composer.removeScene( "view") composer.gotoScene("okno") print("goto okno") return true end function scene:create( event ) local sceneGroup = self.view -- Called when the scene's view does not exist. -- -- INSERT code here to initialize the scene -- e.g. add display objects to 'sceneGroup', add touch listeners, etc. -- create a white background to fill screen local bg = display.newRect( 0, 0, display.contentWidth, display.contentHeight ) bg.anchorX = 0 bg.anchorY = 0 bg:setFillColor( 1 ) -- white -- create some text local title = display.newText( "First View", 0, 0, native.systemFont, 32 ) title:setFillColor( 0 ) -- black title.x = display.contentWidth \* 0.5 title.y = 125 local newTextParams = { text = "Loaded by the first tab's\n\"onPress\" listener\nspecified in the 'tabButtons' table", x = 0, y = 0, width = 310, height = 310, font = native.systemFont, fontSize = 14, align = "center" } local summary = display.newText( newTextParams ) summary:setFillColor( 0 ) -- black summary.x = display.contentWidth \* 0.5 + 10 summary.y = title.y + 215 local function CzatFunction(event) gotoOknoScene(); end local czatButton = widget.newButton { left = 10, width=30, top = 255, label = "Test", onEvent = CzatFunction } -- all objects must be added to group (e.g. self.view) sceneGroup:insert( bg ) sceneGroup:insert( title ) sceneGroup:insert( summary ) sceneGroup:insert(czatButton) 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 elseif phase == "did" then print("view1 SHOW "..phase) -- Called when the scene is now on screen -- -- INSERT code here to make the scene come alive -- e.g. start timers, begin animation, play audio, etc. end end function scene:hide( event ) local sceneGroup = self.view local phase = event.phase if event.phase == "will" then -- Called when the scene is on screen and is about to move off screen -- -- INSERT code here to pause the scene -- e.g. stop timers, stop animation, unload sounds, etc.) elseif phase == "did" then print("view1 HIDE "..phase) -- Called when the scene is now off screen end end function scene:destroy( event ) local sceneGroup = self.view --print( "destroy" ) -- Called prior to the removal of scene's "view" (sceneGroup) -- -- INSERT code here to cleanup the scene -- e.g. remove display objects, remove touch listeners, save state, etc. end --------------------------------------------------------------------------------- -- Listener setup scene:addEventListener( "create", scene ) scene:addEventListener( "show", scene ) scene:addEventListener( "hide", scene ) scene:addEventListener( "destroy", scene ) ----------------------------------------------------------------------------------------- return scene 

okno.lua

local composer = require( "composer" ) local scene = composer.newScene() local widget = require( "widget" ) --------------------------------------------------------------------------------- -- All code outside of the listener functions will only be executed ONCE -- unless "composer.removeScene()" is called. --------------------------------------------------------------------------------- -- local forward references should go here --------------------------------------------------------------------------------- local function gotoViewScene( self, event ) composer.gotoScene("view") return true end -- "scene:create()" function scene:create( event ) local sceneGroup = self.view -- Initialize the scene here. -- Example: add display objects to "sceneGroup", add touch listeners, etc. local function CzatFunction(event) gotoViewScene(); end local czatButton = widget.newButton { left = 10, width=30, top = 255, label = "Back", onEvent = CzatFunction } sceneGroup:insert( czatButton) end -- "scene:show()" function scene:show( event ) local sceneGroup = self.view local phase = event.phase --print("") if ( phase == "will" ) then -- Called when the scene is still off screen (but is about to come on screen). elseif ( phase == "did" ) then print("okno SHOW "..phase) -- Called when the scene is now on screen. -- Insert code here to make the scene come alive. -- Example: start timers, begin animation, play audio, etc. end end -- "scene:hide()" function scene:hide( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then -- Called when the scene is on screen (but is about to go off screen). -- Insert code here to "pause" the scene. -- Example: stop timers, stop animation, stop audio, etc. elseif ( phase == "did" ) then print("okno HIDE "..phase) -- Called immediately after scene goes off screen. end end -- "scene:destroy()" function scene:destroy( event ) local sceneGroup = self.view -- Called prior to the removal of scene's view ("sceneGroup"). -- Insert code here to clean up the scene. -- Example: remove display objects, save state, etc. end --------------------------------------------------------------------------------- -- Listener setup scene:addEventListener( "create", scene ) scene:addEventListener( "show", scene ) scene:addEventListener( "hide", scene ) scene:addEventListener( "destroy", scene ) --------------------------------------------------------------------------------- return scene 

And after back to view1.lua i’ve got

Apr 23 10:05:50.889: goto okno
Apr 23 10:05:50.896: okno SHOW did
Apr 23 10:05:50.896: view1 HIDE did
Apr 23 10:05:51.018: goto okno
Apr 23 10:05:51.028: okno HIDE did
Apr 23 10:05:51.126: okno SHOW did
Apr 23 10:05:57.067: view1 SHOW did
Apr 23 10:05:57.067: okno HIDE did
Apr 23 10:05:57.198: view1 HIDE did
Apr 23 10:05:57.298: view1 SHOW did

why show,hide and again show?

Attache file with example.

Best Regards,

Piotr

onEvent generates multiple events:  a “began” phase and an “ended” phase.  Your function that you’re calling has to test for either the touch down or touch up event and only fire once.  That is:

local function CzatFunction(event)     if event.phase == "ended" then         gotoViewScene();     end     return true end

Or simply don’t use onEvent, instead use onPress or onRelease instead.

Rob

I also had this issue, although in my case the problem was in my button widget handler from my menu module. I had forgotten to place my gotoScene command inside of the button’s “ended” phase. So my menu module was actually going to my game scene multiple times from my button handler. 

Old Code:

local function handlePlay(event) composer.gotoScene("game") end

New Code:

local function handlePlay(event) if event.phase == "ended" then composer.gotoScene("game") end end

Hi,

I have the similar issue with multiple times when i back from another scene.

for example:

view1.lua

----------------------------------------------------------------------------------------- -- -- view1.lua -- ----------------------------------------------------------------------------------------- local composer = require( "composer" ) local scene = composer.newScene() local widget = require( "widget" ) local function gotoOknoScene( self, event ) --composer.removeScene( "view") composer.gotoScene("okno") print("goto okno") return true end function scene:create( event ) local sceneGroup = self.view -- Called when the scene's view does not exist. -- -- INSERT code here to initialize the scene -- e.g. add display objects to 'sceneGroup', add touch listeners, etc. -- create a white background to fill screen local bg = display.newRect( 0, 0, display.contentWidth, display.contentHeight ) bg.anchorX = 0 bg.anchorY = 0 bg:setFillColor( 1 ) -- white -- create some text local title = display.newText( "First View", 0, 0, native.systemFont, 32 ) title:setFillColor( 0 ) -- black title.x = display.contentWidth \* 0.5 title.y = 125 local newTextParams = { text = "Loaded by the first tab's\n\"onPress\" listener\nspecified in the 'tabButtons' table", x = 0, y = 0, width = 310, height = 310, font = native.systemFont, fontSize = 14, align = "center" } local summary = display.newText( newTextParams ) summary:setFillColor( 0 ) -- black summary.x = display.contentWidth \* 0.5 + 10 summary.y = title.y + 215 local function CzatFunction(event) gotoOknoScene(); end local czatButton = widget.newButton { left = 10, width=30, top = 255, label = "Test", onEvent = CzatFunction } -- all objects must be added to group (e.g. self.view) sceneGroup:insert( bg ) sceneGroup:insert( title ) sceneGroup:insert( summary ) sceneGroup:insert(czatButton) 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 elseif phase == "did" then print("view1 SHOW "..phase) -- Called when the scene is now on screen -- -- INSERT code here to make the scene come alive -- e.g. start timers, begin animation, play audio, etc. end end function scene:hide( event ) local sceneGroup = self.view local phase = event.phase if event.phase == "will" then -- Called when the scene is on screen and is about to move off screen -- -- INSERT code here to pause the scene -- e.g. stop timers, stop animation, unload sounds, etc.) elseif phase == "did" then print("view1 HIDE "..phase) -- Called when the scene is now off screen end end function scene:destroy( event ) local sceneGroup = self.view --print( "destroy" ) -- Called prior to the removal of scene's "view" (sceneGroup) -- -- INSERT code here to cleanup the scene -- e.g. remove display objects, remove touch listeners, save state, etc. end --------------------------------------------------------------------------------- -- Listener setup scene:addEventListener( "create", scene ) scene:addEventListener( "show", scene ) scene:addEventListener( "hide", scene ) scene:addEventListener( "destroy", scene ) ----------------------------------------------------------------------------------------- return scene 

okno.lua

local composer = require( "composer" ) local scene = composer.newScene() local widget = require( "widget" ) --------------------------------------------------------------------------------- -- All code outside of the listener functions will only be executed ONCE -- unless "composer.removeScene()" is called. --------------------------------------------------------------------------------- -- local forward references should go here --------------------------------------------------------------------------------- local function gotoViewScene( self, event ) composer.gotoScene("view") return true end -- "scene:create()" function scene:create( event ) local sceneGroup = self.view -- Initialize the scene here. -- Example: add display objects to "sceneGroup", add touch listeners, etc. local function CzatFunction(event) gotoViewScene(); end local czatButton = widget.newButton { left = 10, width=30, top = 255, label = "Back", onEvent = CzatFunction } sceneGroup:insert( czatButton) end -- "scene:show()" function scene:show( event ) local sceneGroup = self.view local phase = event.phase --print("") if ( phase == "will" ) then -- Called when the scene is still off screen (but is about to come on screen). elseif ( phase == "did" ) then print("okno SHOW "..phase) -- Called when the scene is now on screen. -- Insert code here to make the scene come alive. -- Example: start timers, begin animation, play audio, etc. end end -- "scene:hide()" function scene:hide( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then -- Called when the scene is on screen (but is about to go off screen). -- Insert code here to "pause" the scene. -- Example: stop timers, stop animation, stop audio, etc. elseif ( phase == "did" ) then print("okno HIDE "..phase) -- Called immediately after scene goes off screen. end end -- "scene:destroy()" function scene:destroy( event ) local sceneGroup = self.view -- Called prior to the removal of scene's view ("sceneGroup"). -- Insert code here to clean up the scene. -- Example: remove display objects, save state, etc. end --------------------------------------------------------------------------------- -- Listener setup scene:addEventListener( "create", scene ) scene:addEventListener( "show", scene ) scene:addEventListener( "hide", scene ) scene:addEventListener( "destroy", scene ) --------------------------------------------------------------------------------- return scene 

And after back to view1.lua i’ve got

Apr 23 10:05:50.889: goto okno
Apr 23 10:05:50.896: okno SHOW did
Apr 23 10:05:50.896: view1 HIDE did
Apr 23 10:05:51.018: goto okno
Apr 23 10:05:51.028: okno HIDE did
Apr 23 10:05:51.126: okno SHOW did
Apr 23 10:05:57.067: view1 SHOW did
Apr 23 10:05:57.067: okno HIDE did
Apr 23 10:05:57.198: view1 HIDE did
Apr 23 10:05:57.298: view1 SHOW did

why show,hide and again show?

Attache file with example.

Best Regards,

Piotr