Removing all child objects from a view
I am trying to remove all child views from a parent view (possibleTagViewArea) using the following code:
if( possibleTagViewArea.children ){
while( possibleTagViewArea.children.length > 0 ) {
Ti.API.info( 'Number of children: ' + possibleTagViewArea.children.length );
possibleTagViewArea.remove( possibleTagViewArea.children[0] );
Ti.API.info( 'Deleted child at 0' );
}
}
This seems like it should work. I'm simply removing the child at the zero position until the number of children reaches zero. However, I'm getting errors that almost seem to indicate that there is no rhyme or reason to how the child objects are deleted:
[INFO] Number of children: 7
[INFO] Deleted child at 0
[INFO] Number of children: 6
[INFO] Deleted child at 0
[INFO] Number of children: 5
[INFO] Deleted child at 0
[INFO] Number of children: 5
[WARN] Exception in event callback. {
line = 113;
message = "*** -[NSMutableArray objectAtIndex:]: index 4 beyond bounds [0 .. 3]";
sourceId = 245055424;
sourceURL = "file://localhost/Users/me/myapp/Resources/tags.js";
}
Notice that the number of children is output as 5 twice in the debug messages. Running this same portion of code yields errors at a different number of children each time.
Any help is greatly appreciated.
8 Answers
-
Accepted Answer
You might find it easier to wrap the child views in a single view, and remove that from the parent. Have you tried doing that?
-
I think that using the
children
method inside aremove
method is the main problem so I don't mix them.Doing it in two steps seems to work for me. Just save first an array and remove all objects later:
if (view && view.children != undefined) { // Save childrens var removeData = []; for (i = view.children.length; i > 0; i--){ removeData.push(view.children[i - 1]); }; // Remove childrens for (i = 0; i < removeData.length; i++){ view.remove(removeData[i]); } removeData = null; };
-
try looping backwards, i think you will get better results
if( possibleTagViewArea.children ){ while( possibleTagViewArea.children.length!=0 ) { var len = possibleTagViewArea.children.length; Ti.API.info( 'Number of children: ' + len ); possibleTagViewArea.remove( possibleTagViewArea.children[len -1 ] ); Ti.API.info( 'Deleted child at ' + len -1 ); } }
-
Since Ti SDK 3.1, you can call
yourView.removeAllChildren( )
See: http://docs.appcelerator.com/titanium/3.0/#!/api/Titanium.UI.View-method-removeAllChildren
-
Here a possible solution with a recursive function:
function removeChildrens(objeto) { for (i in objeto.children) { var child=objeto.children[0]; removeChildrens(child); objeto.remove(child); child=null; } }
http://gvs-appcelerator.blogspot.com/2012/09/borrar-recursivamente-hijos-de-una.html
-
if(win.children) { while(win.children.length != 0) { var len = win.children.length; win.remove( win.children[0] ); } }
-
This seems to work a little better:
while (thisView.children) { try { thisView.remove(thisView.children[0]); wait(10); } catch (e) { } }
It appears that it takes a finite amount of time to actually remove the child from the view so add a bit of a wait (10 milliseconds worked for me), using a function like this:
function wait (millis) { var date = new Date(); var curDate = null; do { curDate = new Date(); } while(curDate-date < millis); }
-
what I do in my app, with Alloy, using underscore.js, is this:
_.each($.myScroll.children, function(view) { $.myScroll.remove(view); });
Might not be the fastest but easy to understand.