Oct 17 2008

Fixing TextField.bottomScrollV and TextField.maxScrollV

Published by sunny at 5:50 pm under Flash, Tips

There is a rather strange issue with the flash.text.TextField class, one related to the delayed updating of the TextField.bottomScrollV and TextField.maxScrollV properties. The TextField.bottomScrollV indicates the bottommost line that is currently visible in the specified text field while the TextField.maxScrollV indicates the maximum vertical scroll position value.

The problem with these two properties is that they do not update immediately at those times when they should -

(i) when a TextField instance is resized such that the vertical scroll bounds change; and

(ii) when the TextField.wordWrap property changes (from false to true or vice versa).

Some simple code to replicate and demonstrate this issue:

import flash.text.TextField;
 
var txt:TextField = new TextField();
txt.width = 100;
txt.height = 100;
txt.text = "Line 1\nLine 2\nLine 3\nLine 4\nLine 5\nLine 6\nLine 7\nLine 8\nLine 9\nLine 10";
addChild(txt);
trace("bottomScrollV is:"+txt.bottomScrollV); // output 6, correct value
trace("maxScrollV is:"+txt.maxScrollV); // output 5, correct value
 
stage.addEventListener(MouseEvent.CLICK,on_click);
function on_click(evt:MouseEvent):void
{
	txt.height = 50; // ** shrink the height **
	trace("bottomScrollV is:"+txt.bottomScrollV); // output 6, WRONG!
	trace("maxScrollV is:"+txt.maxScrollV); // output 5, WRONG!
}

In the code above, when you click on the stage, the text field is shrunk to 50px height resulting in only 3 lines showing, which means that the bottomScrollV value should have been 3 and the maxScrollV 8, but the values will remain at 6 and 5 respectively… until… supposedly… one frame interval later. Yes, that is what I mean by the delayed updating issue. The same issue applies if you toggle the TextField.wordWrap property.

Apparently, this issue still exists in Flash Player 10.

Admittedly the issue is minor. Perhaps most ActionScripters will never be bothered by it. This is a problem however if you are trying to build accurate text scrollers. I suppose you could work around by living with the “timing” issue and fix it with a “timing” hack, ie checking the properties only next frame interval.

But here is a fix for the issue - just call the TextField.getCharBoundaries() method after the TextField instance is resized (or the wordWrap property has changed). In the example above, we would write the code as:

function on_click(evt:MouseEvent):void
{
	txt.height = 50; // ** shrink the height **
	txt.getCharBoundaries(0);
	trace("bottomScrollV is:"+txt.bottomScrollV); // output 3, CORRECT!
	trace("maxScrollV is:"+txt.maxScrollV); // output 8, CORRECT!
}

Don’t ask me how or why it works. It just does. My guess is perhaps when trying to resolve the character boundaries the TextField instance is forced to re-compute its bounding box and update its scroll properties… It was this guesswork that got me trying anyway, so that would be my explanation if I need to give one.

Once again, simple fix:

	txt.getCharBoundaries(0);

NOTE:
The getCharBoundaries() method accepts one parameter - the index of the character to query - and returns a rectangle that is the bounding box of that specified character. In the above case, however, we use the method only as a fix for the TextField.bottomScrollV and TextField.maxScrollV issue - we just feed any index for the parameter and we are not interested in the rectangle returned…

Trackback URI | Comments RSS

Leave a Reply

*
To prove you're a person (not a spam script), type the security word shown in the picture. Click on the picture to hear an audio file of the word.
Click to hear an audio file of the anti-spam word