Sdílet prostřednictvím


TextKit v Xamarin.iOS

TextKit je nové rozhraní API, které nabízí výkonné funkce rozložení textu a vykreslování. Je postaven na rozhraní Core Text na nízké úrovni, ale je mnohem jednodušší než Základní text.

Aby byly funkce Sady TextKit k dispozici standardním ovládacím prvkům, bylo znovu implementováno několik textových ovládacích prvků pro iOS, aby bylo možné používat TextKit, včetně:

  • UITextView
  • UITextField
  • UILabel

Architektura

TextKit poskytuje vrstvenou architekturu, která odděluje textové úložiště od rozložení a zobrazení, včetně následujících tříd:

  • NSTextContainer – Poskytuje souřadnicový systém a geometrii, které se používají k rozložení textu.
  • NSLayoutManager – Vyloží text tím, že text převede na glyfy.
  • NSTextStorage – Uchovává textová data a také zpracovává aktualizace dávkových textových vlastností. Všechny dávkové aktualizace se předávají správci rozložení pro skutečné zpracování změn, například přepočítání rozložení a překreslení textu.

Tyto tři třídy se použijí v zobrazení, které vykreslí text. Integrovaná zobrazení pro zpracování textu, jako UITextViewje například , UITextFielda UILabel již je máte nastavená, ale můžete je vytvořit a použít i na libovolnou UIView instanci.

Následující obrázek znázorňuje tuto architekturu:

Tento obrázek znázorňuje architekturu TextKitu.

Textové úložiště a atributy

Třída NSTextStorage obsahuje text zobrazený zobrazením. Komunikuje také se všemi změnami textu , jako jsou změny znaků nebo jejich atributů, správci rozložení pro zobrazení. NSTextStorage dědí z MSMutableAttributed řetězce, což umožňuje zadat změny textových atributů v dávkách mezi BeginEditing voláními a EndEditing voláními.

Například následující fragment kódu určuje změnu barvy popředí a pozadí, v uvedeném pořadí a cílí na konkrétní rozsahy:

textView.TextStorage.BeginEditing ();
textView.TextStorage.AddAttribute(UIStringAttributeKey.ForegroundColor, UIColor.Green, new NSRange(200, 400));
textView.TextStorage.AddAttribute(UIStringAttributeKey.BackgroundColor, UIColor.Black, new NSRange(210, 300));
textView.TextStorage.EndEditing ();

Po EndEditing zavolání se změny odešlou správci rozložení, což následně provede veškeré potřebné rozložení a vykreslovací výpočty pro text, který se má zobrazit v zobrazení.

Rozložení s cestou vyloučení

TextKit také podporuje rozložení a umožňuje složité scénáře, jako je text s více sloupci a tok textu kolem zadaných cest označovaných jako cesty vyloučení. Cesty vyloučení se použijí u textového kontejneru, který upraví geometrii rozložení textu, což způsobí, že se text bude pohybovat kolem zadaných cest.

Přidání cesty vyloučení vyžaduje nastavení ExclusionPaths vlastnosti ve správci rozložení. Nastavení této vlastnosti způsobí, že správce rozložení zneplatní rozložení textu a přetéká text kolem cesty vyloučení.

Vyloučení na základě cesty CGPath

Zvažte následující UITextView implementaci podtřídy:

public class ExclusionPathView : UITextView
{
    CGPath exclusionPath;
    CGPoint initialPoint;
    CGPoint latestPoint;
    UIBezierPath bezierPath;

    public ExclusionPathView (string text)
    {
        Text = text;
        ContentInset = new UIEdgeInsets (20, 0, 0, 0);
        BackgroundColor = UIColor.White;
        exclusionPath = new CGPath ();
        bezierPath = UIBezierPath.Create ();

        LayoutManager.AllowsNonContiguousLayout = false;
    }

    public override void TouchesBegan (NSSet touches, UIEvent evt)
    {
        base.TouchesBegan (touches, evt);

        var touch = touches.AnyObject as UITouch;

        if (touch != null) {
            initialPoint = touch.LocationInView (this);
        }
    }

    public override void TouchesMoved (NSSet touches, UIEvent evt)
    {
        base.TouchesMoved (touches, evt);

        UITouch touch = touches.AnyObject as UITouch;

        if (touch != null) {
            latestPoint = touch.LocationInView (this);
            SetNeedsDisplay ();
        }
    }

    public override void TouchesEnded (NSSet touches, UIEvent evt)
    {
        base.TouchesEnded (touches, evt);

        bezierPath.CGPath = exclusionPath;
        TextContainer.ExclusionPaths = new UIBezierPath[] { bezierPath };
    }

    public override void Draw (CGRect rect)
    {
        base.Draw (rect);

        if (!initialPoint.IsEmpty) {

            using (var g = UIGraphics.GetCurrentContext ()) {

                g.SetLineWidth (4);
                UIColor.Blue.SetStroke ();

                if (exclusionPath.IsEmpty) {
                    exclusionPath.AddLines (new CGPoint[] { initialPoint, latestPoint });
                } else {
                    exclusionPath.AddLineToPoint (latestPoint);
                }

                g.AddPath (exclusionPath);
                g.DrawPath (CGPathDrawingMode.Stroke);
            }
        }
    }
}

Tento kód přidává podporu kreslení v textovém zobrazení pomocí základní grafiky. Vzhledem k tomu, že UITextView třída je nyní vytvořena tak, aby používala TextKit pro vykreslování a rozložení textu, může používat všechny funkce Sady TextKit, jako je nastavení cest vyloučení.

Důležité

V tomto příkladu podtřídy UITextView pro přidání podpory dotykového kreslení. Podtřídy UITextView nejsou nutné k získání funkcí Sady TextKit.

Jakmile uživatel nakreslí textové zobrazení, nakreslený CGPath objekt se použije na UIBezierPath instanci nastavením UIBezierPath.CGPath vlastnosti:

bezierPath.CGPath = exclusionPath;

Při aktualizaci následujícího řádku kódu se rozložení textu aktualizuje kolem cesty:

TextContainer.ExclusionPaths = new UIBezierPath[] { bezierPath };

Následující snímek obrazovky ukazuje, jak se rozložení textu mění tak, aby se kolem nakreslené cesty přetékalo:

Tento snímek obrazovky ukazuje, jak se rozložení textu mění tak, aby se kolem nakreslené cesty přetékalo.

Všimněte si, že vlastnost správce AllowsNonContiguousLayout rozložení je v tomto případě nastavená na false. To způsobí přepočítání rozložení pro všechny případy, kdy se text změní. Pokud tuto hodnotu nastavíte na hodnotu True, může to mít za následek zvýšení výkonu tím, že se vyhnete aktualizaci celého rozložení, zejména v případě velkých dokumentů. Nastavení AllowsNonContiguousLayout na hodnotu True by však za určitých okolností zabránilo aktualizaci cesty vyloučení – například pokud je text zadán za běhu bez návratu koncového řádku před nastavením cesty.