Ending Pages.

Iam having an issue where every time I switch pages from a menu to another page functions or text follow over to the next page.

For example I made a scrolling text on a page that follows me when I exit back to the previous page…

Can someone please help with an example on how to prevent this from happening.

Are you using Composer? If you are, it sounds like you’re not inserting your objects into the scene’s display group. If you’re using native.* objects like native.newTextBox(), these do not integrate with Corona’s display hierarchy so you have to remove them before you hide the scene and add them when you show the scene.

Can you share your code where you’re creating an object that sticks around?

Rob

local composer = require( "composer" ) local scene = composer.newScene() local widget = require ( "widget") -- ----------------------------------------------------------------------------------- -- Code outside of the scene event functions below will only be executed ONCE unless -- the scene is removed entirely (not recycled) via "composer.removeScene()" -- ----------------------------------------------------------------------------------- -- Initialize variables local function gotoBackToDrugs() composer.gotoScene( "Drugs", { time=800, effect="crossFade" } ) end -- ----------------------------------------------------------------------------------- -- Scene event functions -- ----------------------------------------------------------------------------------- -- create() function scene:create( event ) local sceneGroup = self.view -- Code here runs when the scene is first created but has not yet appeared on screen local background = display.newImageRect( sceneGroup, "background.png", 800, 1400 ) background.x = display.contentCenterX background.y = display.contentCenterY local Back = display.newText( sceneGroup, "BACK", display.contentCenterX, 50, native.systemFont, 30 ) Back:setFillColor( 0.82, 0.86, 1 ) Back:addEventListener( "tap", gotoBackToDrugs ) end local function scrolllistener ( event ) local phase = event.phase local direction = event.direction if event.limitReached then if "up" == direction then print( "Reached Top Limit" ) elseif "down" == direction then print ( "Reached Bottom Limit" ) end end return true end local scrollView = widget.newScrollView { left = 0, top = 100, width = display.contentWidth, height = display.contentHeight, topPadding = 50, bottomPadding = 50, horizontalScrollDisabled = true, verticalScrollDisabled = false, listener = scrollListener, } local lotsOfText = [["ACTIONS Adenosine exerts its effects by decreasing conduction through the AV mode. The half-life of Adenocard (adenosine) is less than 10 seconds. Thus its effects - both desired and undesired - are self-limited. INDICATIONS Adenocard is indicated for supraventricular tachycardia (SVT), including that associated with accessory bypass tracts (Wolff-Parkinson-White syndrome). When clinically advisable, appropriate vagal maneuvers should be attempted prior to Adenocard administration. CONTRAINDICATIONS Adenocard is contraindicated in second- or third-degree AV block and sick sinus syndrome (except in patients with a functioning artificial pacemaker), and known hypersensitivity to adenosine. PRECAUTIONS The effects of adenosine are antagonized by methylxanthines such as caffeine and theophylline. Thus larger doses may be required for adenosine to be effective in patients who have taken methylxanthines. Adenosine effects are potentiated by dipyridamole (Persantine™). Thus smaller doses of adenosine may be effective in those who have taken this drug. Adenosine may produce bronchoconstriction in patients with asthma. ADVERSE REACTIONS AND SIDE EFFECTS ● Cardiovascular: Facial flushing, headache, and rarely: sweating, palpitations, chest pain, and hypotension. ● Respiratory: Shortness of breath, chest pressure, and rarely: hyperventilating metallic taste, tightness in throat, and head pressure. ● CNS: Light headedness and rarely: dizziness, blurred vision, tingling and numbness in extremities, apprehension. WARNINGS Adenocard may produce a short-lasting first-, second-, or third-degree heart block. In extreme cases, transient asystole may result. At the time of conversion to normal sinus rhythm, a variety of new rhythms may appear (PVCs, PACs sinus bradycardia, sinus tachycardia, skipped beats, and varying degrees of AV block), though they generally last only a few seconds without intervention. DOSAGE Adult: 12 mg rapid IVP immediately followed by 20 mL NS flush. If not resolved repeat in 2 minutes at 12 mg IVP, followed by 20 mL NS flush PRN. Pediatric: 0.1 mg/kg (maximum first dose 6 mg) rapid IVP/IO, immediately followed by 6 mL NS flush. If not resolved repeat in 2 minutes at 0.2 mg/kg (maximum dose 12 mg) rapid IVP, IO followed by 10 mL NS flush PRN. "]] local lotsOfTextObject = display.newText ( lotsOfText, 0, 0, 300, 0, "Helvetica", 14 ) lotsOfTextObject:setTextColor( 0 ) lotsOfTextObject.x = display.contentCenterX scrollView:insert( lotsOfTextObject) -- show() function scene:show( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then -- Code here runs when the scene is still off screen (but is about to come on screen) elseif ( phase == "did" ) then -- Code here runs when the scene is entirely on screen -- Start the music! end end -- hide() function scene:hide( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then -- Code here runs when the scene is on screen (but is about to go off screen) elseif ( phase == "did" ) then -- Code here runs immediately after the scene goes entirely off screen -- Stop the music! audio.stop( 1 ) end end -- destroy() function scene:destroy( event ) local sceneGroup = self.view -- Code here runs prior to the removal of scene's view -- Dispose audio! end -- ----------------------------------------------------------------------------------- -- Scene event function listeners -- ----------------------------------------------------------------------------------- scene:addEventListener( "create", scene ) scene:addEventListener( "show", scene ) scene:addEventListener( "hide", scene ) scene:addEventListener( "destroy", scene ) -- ----------------------------------------------------------------------------------- return scene

I somewhat understand what you’re saying but have no idea on how to implement it. 

This block of code:

local function scrolllistener ( event ) local phase = event.phase local direction = event.direction if event.limitReached then if "up" == direction then print( "Reached Top Limit" ) elseif "down" == direction then print ( "Reached Bottom Limit" ) end end return true end

should be above the scene:create() function.

Follow this block of code with a command to insert the scrollView into the scene group:

local scrollView = widget.newScrollView { left = 0, top = 100, width = display.contentWidth, height = display.contentHeight, topPadding = 50, bottomPadding = 50, horizontalScrollDisabled = true, verticalScrollDisabled = false, listener = scrollListener, } sceneGroup:insert( scrollView ) --\<----- Add this line of code. It's the cause of your problem.

That entire block of code should be inside of your scene:create() function as well as this block of text:

local lotsOfTextObject = display.newText ( lotsOfText, 0, 0, 300, 0, "Helvetica", 14 ) lotsOfTextObject:setTextColor( 0 ) lotsOfTextObject.x = display.contentCenterX scrollView:insert( lotsOfTextObject)

Then your lotsOfText variable that holds your big block of text should be near the top of the module.  Other than the insertion of the scrollView into the sceneGroup, the rest is just better code organization that may come around and bite you later. It technically works now, but best practices are called best practices for a reason.

Finally, when you go to test this on a device, you may find your text not displaying. There is a good chance the display object created by display.newText() may create a texture too large for some mobile devices. You might want to read through this tutorial on how to break that big block of text into multiple display objects that will be reasonable sized textures:

https://docs.coronalabs.com/tutorial/system/textBlocks/index.html

Rob

Great stuff ! So for future reference I should do all my work inside the scene created. I’m just learning little by little how to keep everything organised and where everything goes. 

I got it to work after a few tries and going over the reference you sent :slight_smile: thank you once again.

The different scene events are designed to do things that certain times during your scene’s progress. For instance, if your spawning enemies during play (after the scene is on the screen and working) it doesn’t make any sense to spawn them in scene:create() since that event happens before the scene shows on the screen.

Functions that are not specific to scene creation, like your scrollView listener shouldn’t be inside of any scene:* function because they may get called at times other than the act of creating the scene, showing or hiding the scene.

So do things in scene:create() that are needed to create the scene (load and show your background, create UI elements, etc.) 

The scene:show() has two phases “will” and “did”.  That means scene:show() gets called twice, once just before the scene shows and once just after the scene is fully on the screen. The work that goes on in scene:show() just before the scene shows, would be repositioning object that may have previously moved, or reset scores & lives, etc.  Then when scene:show() gets called again during the “did” phase, that’s a great time to “start” things up. You don’t want to start transitions, physics, etc. during scene:create() or before the scene shows() because objects will have moved before the user can see them.

Rob

Are you using Composer? If you are, it sounds like you’re not inserting your objects into the scene’s display group. If you’re using native.* objects like native.newTextBox(), these do not integrate with Corona’s display hierarchy so you have to remove them before you hide the scene and add them when you show the scene.

Can you share your code where you’re creating an object that sticks around?

Rob

local composer = require( "composer" ) local scene = composer.newScene() local widget = require ( "widget") -- ----------------------------------------------------------------------------------- -- Code outside of the scene event functions below will only be executed ONCE unless -- the scene is removed entirely (not recycled) via "composer.removeScene()" -- ----------------------------------------------------------------------------------- -- Initialize variables local function gotoBackToDrugs() composer.gotoScene( "Drugs", { time=800, effect="crossFade" } ) end -- ----------------------------------------------------------------------------------- -- Scene event functions -- ----------------------------------------------------------------------------------- -- create() function scene:create( event ) local sceneGroup = self.view -- Code here runs when the scene is first created but has not yet appeared on screen local background = display.newImageRect( sceneGroup, "background.png", 800, 1400 ) background.x = display.contentCenterX background.y = display.contentCenterY local Back = display.newText( sceneGroup, "BACK", display.contentCenterX, 50, native.systemFont, 30 ) Back:setFillColor( 0.82, 0.86, 1 ) Back:addEventListener( "tap", gotoBackToDrugs ) end local function scrolllistener ( event ) local phase = event.phase local direction = event.direction if event.limitReached then if "up" == direction then print( "Reached Top Limit" ) elseif "down" == direction then print ( "Reached Bottom Limit" ) end end return true end local scrollView = widget.newScrollView { left = 0, top = 100, width = display.contentWidth, height = display.contentHeight, topPadding = 50, bottomPadding = 50, horizontalScrollDisabled = true, verticalScrollDisabled = false, listener = scrollListener, } local lotsOfText = [["ACTIONS Adenosine exerts its effects by decreasing conduction through the AV mode. The half-life of Adenocard (adenosine) is less than 10 seconds. Thus its effects - both desired and undesired - are self-limited. INDICATIONS Adenocard is indicated for supraventricular tachycardia (SVT), including that associated with accessory bypass tracts (Wolff-Parkinson-White syndrome). When clinically advisable, appropriate vagal maneuvers should be attempted prior to Adenocard administration. CONTRAINDICATIONS Adenocard is contraindicated in second- or third-degree AV block and sick sinus syndrome (except in patients with a functioning artificial pacemaker), and known hypersensitivity to adenosine. PRECAUTIONS The effects of adenosine are antagonized by methylxanthines such as caffeine and theophylline. Thus larger doses may be required for adenosine to be effective in patients who have taken methylxanthines. Adenosine effects are potentiated by dipyridamole (Persantine™). Thus smaller doses of adenosine may be effective in those who have taken this drug. Adenosine may produce bronchoconstriction in patients with asthma. ADVERSE REACTIONS AND SIDE EFFECTS ● Cardiovascular: Facial flushing, headache, and rarely: sweating, palpitations, chest pain, and hypotension. ● Respiratory: Shortness of breath, chest pressure, and rarely: hyperventilating metallic taste, tightness in throat, and head pressure. ● CNS: Light headedness and rarely: dizziness, blurred vision, tingling and numbness in extremities, apprehension. WARNINGS Adenocard may produce a short-lasting first-, second-, or third-degree heart block. In extreme cases, transient asystole may result. At the time of conversion to normal sinus rhythm, a variety of new rhythms may appear (PVCs, PACs sinus bradycardia, sinus tachycardia, skipped beats, and varying degrees of AV block), though they generally last only a few seconds without intervention. DOSAGE Adult: 12 mg rapid IVP immediately followed by 20 mL NS flush. If not resolved repeat in 2 minutes at 12 mg IVP, followed by 20 mL NS flush PRN. Pediatric: 0.1 mg/kg (maximum first dose 6 mg) rapid IVP/IO, immediately followed by 6 mL NS flush. If not resolved repeat in 2 minutes at 0.2 mg/kg (maximum dose 12 mg) rapid IVP, IO followed by 10 mL NS flush PRN. "]] local lotsOfTextObject = display.newText ( lotsOfText, 0, 0, 300, 0, "Helvetica", 14 ) lotsOfTextObject:setTextColor( 0 ) lotsOfTextObject.x = display.contentCenterX scrollView:insert( lotsOfTextObject) -- show() function scene:show( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then -- Code here runs when the scene is still off screen (but is about to come on screen) elseif ( phase == "did" ) then -- Code here runs when the scene is entirely on screen -- Start the music! end end -- hide() function scene:hide( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then -- Code here runs when the scene is on screen (but is about to go off screen) elseif ( phase == "did" ) then -- Code here runs immediately after the scene goes entirely off screen -- Stop the music! audio.stop( 1 ) end end -- destroy() function scene:destroy( event ) local sceneGroup = self.view -- Code here runs prior to the removal of scene's view -- Dispose audio! end -- ----------------------------------------------------------------------------------- -- Scene event function listeners -- ----------------------------------------------------------------------------------- scene:addEventListener( "create", scene ) scene:addEventListener( "show", scene ) scene:addEventListener( "hide", scene ) scene:addEventListener( "destroy", scene ) -- ----------------------------------------------------------------------------------- return scene

I somewhat understand what you’re saying but have no idea on how to implement it. 

This block of code:

local function scrolllistener ( event ) local phase = event.phase local direction = event.direction if event.limitReached then if "up" == direction then print( "Reached Top Limit" ) elseif "down" == direction then print ( "Reached Bottom Limit" ) end end return true end

should be above the scene:create() function.

Follow this block of code with a command to insert the scrollView into the scene group:

local scrollView = widget.newScrollView { left = 0, top = 100, width = display.contentWidth, height = display.contentHeight, topPadding = 50, bottomPadding = 50, horizontalScrollDisabled = true, verticalScrollDisabled = false, listener = scrollListener, } sceneGroup:insert( scrollView ) --\<----- Add this line of code. It's the cause of your problem.

That entire block of code should be inside of your scene:create() function as well as this block of text:

local lotsOfTextObject = display.newText ( lotsOfText, 0, 0, 300, 0, "Helvetica", 14 ) lotsOfTextObject:setTextColor( 0 ) lotsOfTextObject.x = display.contentCenterX scrollView:insert( lotsOfTextObject)

Then your lotsOfText variable that holds your big block of text should be near the top of the module.  Other than the insertion of the scrollView into the sceneGroup, the rest is just better code organization that may come around and bite you later. It technically works now, but best practices are called best practices for a reason.

Finally, when you go to test this on a device, you may find your text not displaying. There is a good chance the display object created by display.newText() may create a texture too large for some mobile devices. You might want to read through this tutorial on how to break that big block of text into multiple display objects that will be reasonable sized textures:

https://docs.coronalabs.com/tutorial/system/textBlocks/index.html

Rob

Great stuff ! So for future reference I should do all my work inside the scene created. I’m just learning little by little how to keep everything organised and where everything goes. 

I got it to work after a few tries and going over the reference you sent :slight_smile: thank you once again.

The different scene events are designed to do things that certain times during your scene’s progress. For instance, if your spawning enemies during play (after the scene is on the screen and working) it doesn’t make any sense to spawn them in scene:create() since that event happens before the scene shows on the screen.

Functions that are not specific to scene creation, like your scrollView listener shouldn’t be inside of any scene:* function because they may get called at times other than the act of creating the scene, showing or hiding the scene.

So do things in scene:create() that are needed to create the scene (load and show your background, create UI elements, etc.) 

The scene:show() has two phases “will” and “did”.  That means scene:show() gets called twice, once just before the scene shows and once just after the scene is fully on the screen. The work that goes on in scene:show() just before the scene shows, would be repositioning object that may have previously moved, or reset scores & lives, etc.  Then when scene:show() gets called again during the “did” phase, that’s a great time to “start” things up. You don’t want to start transitions, physics, etc. during scene:create() or before the scene shows() because objects will have moved before the user can see them.

Rob