I have a text field with a set height and width and that allows word wrapping. When I add text to it, I dynamically change the font size until the height of the text is smaller than the height of the box, allowing it to properly fit. The problem I am running into is that the box is fairly thin by necessity, and some longer words (like "Australia") are broken during the word wrap. So, perhaps "Australi" will show up on the first line, and "a" on the second line. However, because they satisfy the height requirement, they aren't shrunk any more. I need a way to detect this and continue shrinking these cases so they fit without the break. Here is the code for dynamically shrinking the text to fit the height:
text.wordWrap = true;
text.autoSize = TextFieldAutoSize.CENTER;
while(text.height > textBoxVal) {
myFormat.size = Number(myFormat.size) - 2;
text.defaultTextFormat = myFormat;
text.setTextFormat(myFormat);
}
This works fine. The problem with my approach to the next step (shrinking if horizontal constraints are not met because of a word being split) is that by leaving text.wordWrap
set to true, the longer words will still break and never be resized, but setting it to false means that the other boxes that were fine before because of word wrap being on (like "United States") are now too long on a single line, and are shrunk when they shouldn't be. For what it's worth, here's my code to shrink horizontally (immediately follows above code):
text.wordWrap = false;
text.autoSize = TextFieldAutoSize.LEFT;
while(text.width > textBoxVal) {
myFormat.size = Number(myFormat.size) - 2;
text.defaultTextFormat = myFormat开发者_JS百科;
text.setTextFormat(myFormat);
}
Is there a better way to go about this? Perhaps some way to force ActionScript not to break words, etc?
Edit: To give an example, please look at the screenshot below:
This is using only the first code block, which ensures that the text fits into the box's vertical constraints. You can see that some boxes (like the first for the US) are fine, whereas some of the smaller ones (like the last few) are split. Using my second code block to resize the horizontal constraints makes no changes if word wrap is true, and will make all boxes (including ones that are fine, like the US) smaller than needed if word wrap is set to false.
If your text wraps to another line, you should be able to check maxScrollV.
My guess below:
while((text.height > textBoxVal || text.maxScrollV > 1) && myFormat.size > 1) {
myFormat.size = Math.max(1, Number(myFormat.size) - 2);
text.defaultTextFormat = myFormat;
text.setTextFormat(myFormat);
}
EDIT
What I suggest is
- add text into field word by word
- if maxScrollV changes, you get an automatic word wrap
- insert implicit line break
- resize the text to fit desired height
- repeat until all words are not there
Here is some code to illustrate that:
private function fitText (text:String, rect:Rectangle, tf:TextField, format:TextFormat) : void
{
// split text by whitespace
var heap:Array = text.split(/\s+/);
var size:uint = format.size;
var maxScroll:uint = 1;
var text:String;
var word:String;
// make sure tf is set up correctly
tf.defaultTextFormat = format;
tf.setTextFormat(format);
tf.multiline = true;
tf.wordWrap = true;
tf.autoSize = TextFieldAutoSize.LEFT;
tf.width = rect.width;
for (var i:uint = 0; i<heap.length;i+=1) {
// insert text word by word
word = heap[i];
text = tf.text;
if (i) {
tf.text = text + " " + word;
} else {
tf.text = word;
}
if (tf.maxScrollV > maxScroll) {
// the last word you inserted increased number of lines
// and possibly got broken
// increase scroll by 1
// if scroll actually increased by more than 1,
// we got word broken multiple times
maxScroll += 1;
// insert implicit line break, if not the first word
if (i) {
tf.text = text + "\n" + word;
}
}
// do the resizing routine, if needed
while (tf.height > rect.height || tf.maxScrollV > maxScroll) {
// we also check tf.maxScrollV,
// as it can be no more than maxScroll.
// otherwise we'll get words crippled
/*resizing code here*/
}
}
// restore original size
format.size = size;
}
Skim over this, It may help you detect the situations.
Pay special attention to him having to wait 1 frame to be able to detect the unwanted linebreak.
The second you detect it then you can size down a bit more and re-detect for the unsavory line break.
http://troyworks.com/blog/2011/06/09/flash-as3-detect-undesired-line-break-in-textfield-wordwrap-is-true/
精彩评论