Aracılığıyla paylaş


Xamarin.iOS'ta TextKit

TextKit, güçlü metin düzeni ve işleme özellikleri sunan yeni bir API'dir. Alt düzey Core Text çerçevesinin üzerine kurulmuştur, ancak kullanımı Çekirdek Metin'den çok daha kolaydır.

TextKit'in özelliklerini standart denetimlerin kullanımına açmak için, TextKit'i kullanmak için aşağıdakiler dahil olmak üzere birkaç iOS metin denetimi yeniden uygulanmıştır:

  • UITextView
  • UITextField
  • UILabel

Mimari

TextKit, aşağıdaki sınıflar da dahil olmak üzere metin depolama alanını düzen ve görüntüden ayıran katmanlı bir mimari sağlar:

  • NSTextContainer – Metni düzenlemek için kullanılan koordinat sistemini ve geometriyi sağlar.
  • NSLayoutManager – Metni gliflere dönüştürerek yerleştirir.
  • NSTextStorage – Metin verilerini tutar ve toplu metin özellik güncelleştirmelerini işler. Tüm toplu güncelleştirmeler, düzeni yeniden hesaplama ve metni yeniden çizme gibi değişikliklerin gerçek işlenmesi için düzen yöneticisine teslim edilir.

Bu üç sınıf, metin işleyen bir görünüme uygulanır. , ve gibi UITextViewUITextFieldUILabel yerleşik metin işleme görünümleri zaten ayarlanmıştır, ancak bunları oluşturabilir ve herhangi bir UIView örneğe de uygulayabilirsiniz.

Aşağıdaki şekilde bu mimari gösterilmektedir:

Bu şekilde TextKit mimarisi gösterilmektedir

Metin Depolama ve Öznitelikleri

sınıfı, NSTextStorage bir görünüm tarafından görüntülenen metni tutar. Ayrıca, metindeki tüm değişiklikleri (karakterlerdeki veya özniteliklerindeki değişiklikler gibi) görüntü için düzen yöneticisine iletir. NSTextStoragedizeden MSMutableAttributed devralır ve metin özniteliklerinde yapılan değişikliklerin ve EndEditing çağrıları arasında BeginEditing toplu olarak belirtilmesine izin verir.

Örneğin, aşağıdaki kod parçacığı sırasıyla ön plan ve arka plan renklerinde bir değişiklik belirtir ve belirli aralıkları hedefler:

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 ();

Çağrıldıktan sonra EndEditing , değişiklikler düzen yöneticisine gönderilir ve bu da görünümde görüntülenecek metin için gerekli düzen ve işleme hesaplamalarını gerçekleştirir.

Dışlama Yolu ile Düzen

TextKit ayrıca düzeni destekler ve çok sütunlu metin ve dışlama yolları olarak adlandırılan belirtilen yolların çevresinde akan metin gibi karmaşık senaryolara olanak tanır. Dışlama yolları, metin düzeninin geometrisini değiştirerek metnin belirtilen yollarda akmasına neden olan metin kapsayıcısına uygulanır.

Dışlama yolu eklemek için düzen yöneticisinde ExclusionPaths özelliğin ayarlanması gerekir. Bu özelliğin ayarlanması, düzen yöneticisinin metin düzenini geçersiz kılmasını ve metni dışlama yolunun çevresinde akmasını sağlar.

CGPath tabanlı dışlama

Aşağıdaki UITextView alt sınıf uygulamasını göz önünde bulundurun:

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);
            }
        }
    }
}

Bu kod, Temel Grafikleri kullanarak metin görünümünde çizim için destek ekler. UITextView Sınıfı artık metin işleme ve düzeni için TextKit kullanacak şekilde oluşturulduğundan, dışlama yollarını ayarlama gibi TextKit'in tüm özelliklerini kullanabilir.

Önemli

Bu örnek, dokunmatik çizim desteği eklemek için alt sınıflar UITextView . TextKit'in özelliklerini almak için alt sınıflama UITextView gerekli değildir.

Kullanıcı metin görünümünde çizim yaptıktan sonra, çizilen CGPath özellik ayarlanarak UIBezierPath.CGPath örneğe UIBezierPath uygulanır:

bezierPath.CGPath = exclusionPath;

Aşağıdaki kod satırının güncelleştirilmesi, metin düzeninin yol çevresinde güncelleştirilmesini sağlar:

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

Aşağıdaki ekran görüntüsünde, metin düzeninin çizilmiş yol etrafında akacak şekilde nasıl değiştiği gösterilmektedir:

Bu ekran görüntüsünde, metin düzeninin çizilmiş yol etrafında akacak şekilde nasıl değiştiği gösterilmektedir

Bu durumda düzen yöneticisinin AllowsNonContiguousLayout özelliğinin false olarak ayarlandığına dikkat edin. Bu, metnin değiştiği tüm durumlar için düzenin yeniden hesaplanmasına neden olur. Bunu true olarak ayarlamak, özellikle de büyük belgeler söz konusu olduğunda tam düzen yenilemeden kaçınarak performansa fayda sağlayabilir. Ancak true olarak ayarlanması AllowsNonContiguousLayout , dışlama yolunun bazı durumlarda düzeni güncelleştirmesini engeller. Örneğin, çalışma zamanında metin ayarlanmadan önce sondaki satır başı olmadan girilirse.