Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
O TextKit é uma nova API que oferece recursos poderosos de layout e renderização de texto. Ele é construído sobre a estrutura de baixo nível Core Text, mas é muito mais fácil de usar do que o Core Text.
Para tornar os recursos do TextKit disponíveis para controles padrão, vários controles de texto do iOS foram reimplementados para usar o TextKit, incluindo:
- UITextView
- UITextField
- UILabel
Arquitetura
O TextKit fornece uma arquitetura em camadas que separa o armazenamento de texto do layout e da exibição, incluindo as seguintes classes:
NSTextContainer– Fornece o sistema de coordenadas e geometria que é usado para layout de texto.NSLayoutManager– Estabelece texto transformando texto em glifos.NSTextStorage– Mantém os dados de texto, bem como manipula atualizações de propriedades de texto em lote. Todas as atualizações em lote são entregues ao gerenciador de layout para o processamento real das alterações, como recalcular o layout e redesenhar o texto.
Essas três classes são aplicadas a um modo de exibição que renderiza texto. Os modos de exibição internos de manipulação de texto, como UITextView, UITextFielde UILabel já os têm definidos, mas você também pode criá-los e aplicá-los a qualquer UIView instância.
A figura a seguir ilustra essa arquitetura:

Armazenamento de texto e atributos
A NSTextStorage classe contém o texto que é exibido por um modo de exibição. Ele também comunica quaisquer alterações no texto - como alterações em caracteres ou seus atributos - ao gerenciador de layout para exibição. NSTextStorage herda da cadeia de caracteres, permitindo que as alterações nos atributos de MSMutableAttributed texto sejam especificadas em lotes entre BeginEditing e EndEditing chamadas.
Por exemplo, o trecho de código a seguir especifica uma alteração nas cores de primeiro plano e plano de fundo, respectivamente, e destina-se a intervalos específicos:
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 ();
Depois EndEditing de chamado, as alterações são enviadas para o gerenciador de layout, que por sua vez executa todos os cálculos de layout e renderização necessários para que o texto seja exibido na exibição.
Layout com caminho de exclusão
O TextKit também oferece suporte a layout e permite cenários complexos, como texto de várias colunas e texto fluindo em caminhos especificados chamados caminhos de exclusão. Os caminhos de exclusão são aplicados ao contêiner de texto, que modifica a geometria do layout de texto, fazendo com que o texto flua em torno dos caminhos especificados.
A adição de um caminho de exclusão requer a configuração da ExclusionPaths propriedade no gerenciador de layout. A definição dessa propriedade faz com que o gerenciador de layout invalide o layout de texto e flua o texto ao redor do caminho de exclusão.
Exclusão com base em um CGPath
Considere a seguinte UITextView implementação de subclasse:
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);
}
}
}
}
Esse código adiciona suporte para desenho no modo de exibição de texto usando elementos gráficos principais. Como a classe agora foi criada para usar o UITextView TextKit para sua renderização e layout de texto, ela pode usar todos os recursos do TextKit, como definir caminhos de exclusão.
Importante
Este exemplo subclasses UITextView para adicionar suporte a desenho por toque. A subclassificação UITextView não é necessária para obter os recursos do TextKit.
Depois que o usuário desenha no modo de exibição de texto, o desenho CGPath é aplicado a uma UIBezierPath instância definindo a UIBezierPath.CGPath propriedade:
bezierPath.CGPath = exclusionPath;
A atualização da seguinte linha de código faz com que o layout de texto seja atualizado ao redor do caminho:
TextContainer.ExclusionPaths = new UIBezierPath[] { bezierPath };
A captura de tela a seguir ilustra como o layout do texto muda para fluir ao redor do caminho desenhado:

Observe que a propriedade do gerenciador de AllowsNonContiguousLayout layout é definida como false nesse caso. Isso faz com que o layout seja recalculado para todos os casos em que o texto é alterado. Definir isso como true pode beneficiar o desempenho, evitando uma atualização de layout completo, especialmente no caso de documentos grandes. No entanto, definir AllowsNonContiguousLayout como true impediria que o caminho de exclusão atualizasse o layout em algumas circunstâncias - por exemplo, se o texto for inserido em tempo de execução sem um retorno de carro à direita antes do caminho ser definido.