TextKit v Xamarin.iOS

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

Aby byly funkce TextKitu dostupné standardním ovládacím prvkům, bylo znovu implementováno několik textových ovládacích prvků pro iOS, které používají 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é slouží k rozložení textu.
  • NSLayoutManager – Rozloží 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í pro zobrazení, které vykresluje text. Integrovaná zobrazení pro zpracování textu, například UITextView, UITextFielda UILabel již je mají 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:

This figure illustrates the TextKit architecture

Textové Storage a atributy

Třída NSTextStorage obsahuje text, který je zobrazen zobrazením. Komunikuje také se správcem rozložení pro zobrazení všechny změny textu , například změny znaků nebo jejich atributů. NSTextStorage dědí z MSMutableAttributed řetězce, což umožňuje zadat změny atributů textu 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 posílají správci rozložení, který následně provede veškeré potřebné rozložení a vykreslovací výpočty pro zobrazení textu.

Rozložení s cestou vyloučení

Sada 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í tok textu 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 tok textu kolem cesty vyloučení.

Vyloučení založené na CGPathu

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 třída je nyní sestavena UITextView 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 přidáte podporu dotykového kreslení. Podtřídy UITextView nejsou nutné k získání funkcí Sady TextKit.

Jakmile uživatel nakreslí textové zobrazení, nakreslený CGPath 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 kolem cesty aktualizuje rozložení textu:

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

Následující snímek obrazovky znázorňuje, jak se rozložení textu mění tak, aby tok kolem nakreslené cesty:

This screenshot illustrates how the text layout changes to flow around the drawn path

Všimněte si, že vlastnost správce AllowsNonContiguousLayout rozložení je v tomto případě nastavena na false. To způsobí přepočítání rozložení pro všechny případy, kdy se text změní. Nastavení této hodnoty na hodnotu True může výhodou výkonu tím, že se vyhnete aktualizaci v plném 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í rozložení , například pokud je text zadán za běhu bez koncového návratu na začátek řádku před nastavením cesty.