TextKit di Xamarin.iOS
TextKit adalah API baru yang menawarkan tata letak teks dan fitur penyajian yang canggih. Ini dibangun di atas kerangka kerja Teks Inti tingkat rendah, tetapi jauh lebih mudah digunakan daripada Core Text.
Untuk membuat fitur TextKit tersedia untuk kontrol standar, beberapa kontrol teks iOS telah diimplementasikan ulang untuk menggunakan TextKit, termasuk:
- UITextView
- UITextField
- UILabel
Sistem
TextKit menyediakan arsitektur berlapis yang memisahkan penyimpanan teks dari tata letak dan tampilan, termasuk kelas berikut:
NSTextContainer
– Menyediakan sistem koordinat dan geometri yang digunakan untuk tata letak teks.NSLayoutManager
– Menata teks dengan mengubah teks menjadi glyph.NSTextStorage
– Menyimpan data teks, serta menangani pembaruan properti teks batch. Setiap pembaruan batch diserahkan ke manajer tata letak untuk pemrosesan perubahan aktual, seperti menghitung ulang tata letak dan menggambar ulang teks.
Ketiga kelas ini diterapkan ke tampilan yang merender teks. Tampilan penanganan teks bawaan, seperti UITextView
, , dan UILabel
sudah mengaturnya, tetapi Anda juga dapat membuat dan menerapkannya ke instans apa pun UIView
UITextField
.
Gambar berikut mengilustrasikan arsitektur ini:
Penyimpanan teks dan Atribut
Kelas NSTextStorage
menyimpan teks yang ditampilkan oleh tampilan. Ini juga mengomunikasikan perubahan apa pun pada teks - seperti perubahan pada karakter atau atributnya - ke manajer tata letak untuk ditampilkan. NSTextStorage
mewarisi dari MSMutableAttributed
string, memungkinkan perubahan pada atribut teks ditentukan dalam batch antara BeginEditing
dan EndEditing
panggilan.
Misalnya, cuplikan kode berikut menentukan perubahan pada warna latar depan dan latar belakang, masing-masing, dan menargetkan rentang tertentu:
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 ();
Setelah EndEditing
dipanggil, perubahan dikirim ke manajer tata letak, yang pada gilirannya melakukan tata letak dan perhitungan penyajian yang diperlukan agar teks ditampilkan dalam tampilan.
Tata letak dengan Jalur Pengecualian
TextKit juga mendukung tata letak, dan memungkinkan skenario kompleks seperti teks multi-kolom dan teks mengalir di sekitar jalur tertentu yang disebut jalur pengecualian. Jalur pengecualian diterapkan ke kontainer teks, yang memodifikasi geometri tata letak teks, menyebabkan teks mengalir di sekitar jalur yang ditentukan.
Menambahkan jalur pengecualian memerlukan pengaturan ExclusionPaths
properti pada manajer tata letak. Mengatur properti ini menyebabkan pengelola tata letak membatalkan tata letak teks dan mengalirkan teks di sekitar jalur pengecualian.
Pengecualian berdasarkan CGPath
Pertimbangkan implementasi subkelas berikut UITextView
:
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);
}
}
}
}
Kode ini menambahkan dukungan untuk menggambar pada tampilan teks menggunakan Core Graphics. UITextView
Karena kelas sekarang dibangun untuk menggunakan TextKit untuk penyajian teks dan tata letaknya, kelas dapat menggunakan semua fitur TextKit, seperti mengatur jalur pengecualian.
Penting
Contoh subkelas UITextView
ini untuk menambahkan dukungan gambar sentuhan. Subkelas UITextView
tidak diperlukan untuk mendapatkan fitur TextKit.
Setelah pengguna menggambar tampilan teks, gambar CGPath
diterapkan ke UIBezierPath
instans dengan mengatur UIBezierPath.CGPath
properti :
bezierPath.CGPath = exclusionPath;
Memperbarui baris kode berikut membuat tata letak teks diperbarui di sekitar jalur:
TextContainer.ExclusionPaths = new UIBezierPath[] { bezierPath };
Cuplikan layar berikut menggambarkan bagaimana tata letak teks berubah untuk mengalir di sekitar jalur yang digambar:
Perhatikan bahwa properti manajer AllowsNonContiguousLayout
tata letak diatur ke false dalam kasus ini. Ini menyebabkan tata letak dihitung ulang untuk semua kasus di mana teks berubah. Mengatur ini ke true dapat menguntungkan performa dengan menghindari refresh tata letak penuh, terutama dalam kasus dokumen besar. Namun, pengaturan AllowsNonContiguousLayout
ke true akan mencegah jalur pengecualian memperbarui tata letak dalam beberapa keadaan - misalnya, jika teks dimasukkan pada runtime tanpa pengembalian pengangkutan berikutnya sebelum jalur diatur.