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 UITextView
UITextField
UILabel
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:
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. NSTextStorage
dizeden 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 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.