【问题标题】:AS3 - Why is the font being cleared after setting text of a TextField?AS3 - 为什么设置 TextField 的文本后字体被清除?
【发布时间】:2016-03-30 18:01:25
【问题描述】:

我有以下设置:在 Label.fla 中有一个包含 TextField 的 MovieClip,它的类设置为 src.components.Label。这个类所做的只是在构造函数中设置字体,然后将 TextField 的 text 属性设置为空字符串(字符串的值与此问题无关。它可以是非空字符串并且具有相同的结果)。像这样:

package src.components
{
    import flash.display.MovieClip;
    import flash.text.TextFormat;
    import flash.text.TextField;

    public class Label extends MovieClip
    {
        public var mTextField:TextField;

        public function Label()
        {
            super();

            var tf:TextFormat = new TextFormat("Arial", 34, 0xFFFFFF);
            mTextField.defaultTextFormat = tf;
            mTextField.setTextFormat(tf);

            trace("init before: " + mTextField.getTextFormat().font);
            mTextField.text = "";
            trace("init after: " + mTextField.getTextFormat().font);
        }
    }
}

Label.fla 中的标签对象设置为导出用于运行时共享,已复制到 MainMenu.fla。此标签的单个实例放置在 MainMenu.fla 的舞台上,当我运行 MainMenu.swf 时,输出清楚地显示正在设置字体,然后立即清除,因为我正在更改 TextField 的文本属性。

输出如下:

init before: Arial
init after: null

为什么设置文本会导致字体被清除?这给我带来了很多问题。我想出解决这个问题的唯一方法是做一些愚蠢的事情,在设置文本之前复制 TextFormat 对象,设置文本,然后重新应用复制的 TextFormat 以确保它不会改变.

我附上了一个包含所有源文件和编译文件的 zip 文件,以进行测试。 FontTest.zip

【问题讨论】:

    标签: actionscript-3 flash fonts textfield


    【解决方案1】:

    这个问题的简短回答是这样的:

    • 因为您没有阅读文档。

    没错,这是您的代码中唯一的问题。您使用的方法 (setTextFormat(tf)) 仅用于设置当前现有文本的格式。这当然是在文档中指定的。

    为任何未来设置的文本设置格式的一种方法是:“defaultTextFormat”。这再次在文档中指定,并且此方法不会修改已在文本字段中设置的文本。

    所以 2 种方法意味着 2 种不同的东西,一种(您使用的)用于修改现有文本,另一种用于修改任何未来文本的“defaultTextFormat”。

    但真正阅读文档会为您节省一趟 SO,阅读 as3 文档并回答您未来 99% 的问题。

    【讨论】:

    • 即使有文档,我也不能 100% 理解 defaultTextFormat 是如何工作的。我正在设置它,所以我希望它会在更改文本后应用它。虽然在重新阅读文档后,它只提到了使用 replaceSelectedText() 和 setSelection(),所以也许只有这两个函数有效?我将不得不更多地解决这个问题......
    【解决方案2】:

    扩展了 BotMaster 发布的内容,我重新阅读了文档并找出了我误解的地方。如果您想在使用 defaultTextFormat 时保持文本格式,您可以使用 setSelection() 后跟 replaceSelectedText() 设置文本。所以固定的构造函数是这样的:

    public function Label()
    {
        super();
    
        var tf:TextFormat = new TextFormat("Arial", 34, 0xFFFFFF);
        mTextField.defaultTextFormat = tf;
    
        trace("init before: " + mTextField.getTextFormat().font);
        mTextField.setSelection(0, mTextField.length);
        mTextField.replaceSelectedText("");
        trace("init after: " + mTextField.getTextFormat().font);
    }
    

    这会生成以下输出:

    init before: Bender
    init after: Arial
    

    Bender 是在 FLA 中设置的字体,因此这是预期的起始值。

    作为替代解决方案,您可以存储 TextFormat 对象并在设置 text 属性后应用它,但我不确定哪个更有效。该解决方案如下所示:

    public class Label extends MovieClip
    {
        public var mTextField:TextField;
        private var mTextFormat:TextFormat = null;
    
        public function Label()
        {
            super();
    
            // Storing this in a member so that anywhere in this class that you change the text
            // you can just apply it without having to reconstructing it.
            mTextFormat = new TextFormat("Arial", 34, 0xFFFFFF);
    
            trace("init before: " + mTextField.getTextFormat().font);
            mTextField.text = "";
            mTextField.setTextFormat(mTextFormat);
            trace("init after: " + mTextField.getTextFormat().font);
        }
    }
    

    【讨论】:

    • 我很困惑...如果您使用 Arial 字体设置 mTextField.defaultTextFormat = tf;,那么当您使用 trace("init before: "... 时它为什么会跟踪 Bender 但无论如何我认为您为我解决了一个老问题。我总是通过代码创建文本字段,因为如果已经在舞台上(由“文本”图标创建),它不会更新文本格式。看起来工作技巧是replaceSelectedText("");。这甚至可能是一个 Flash 错误。我稍后会检查...
    • 它输出 Bender,因为设置 defaultTextFormat 不会将该格式应用于现有文本。在我调用 replaceSelectedText() 之前它不会应用它。
    • 代码已从原始问题更改。使用 defaultTextFormat 不会将格式应用于之前设置的文本,但会将格式应用于之后设置的文本,使用 setTextFormat 的工作方式完全相反。
    猜你喜欢
    • 2011-12-18
    • 1970-01-01
    • 1970-01-01
    • 2013-07-17
    • 1970-01-01
    • 1970-01-01
    • 2011-03-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多