2011-12-30 12 views
7

Estoy tratando de mostrar un UIPopoverController de la rect de un texto seleccionado en un UITextView, ¿Cómo puedo obtener el texto seleccionado CGRect?¿Cómo puedo obtener el marco de texto seleccionado de una UITextView

Gracias!

+0

Si esta pregunta es lo que creo que es, UIPopoverController en el título es probablemente engañosa? ¿Desea obtener el CGPoint de la selección de texto, no es nada especial para UIPopoverController, ¿verdad? – barley

+0

Se corrigió el título ya que su sugerencia es válida @barley. – Till

Respuesta

33

Creo que [UITextInput selectedTextRange] y [UITextInput caretRectForPosition:] es lo que estás buscando.

[UITextInput selectedTextRange] devuelve el rango seleccionado en el carácter

[UITextInput caretRectForPosition:] devuelve el CGRect de la gama de personaje en esta entrada.

UITextView cumple con UITextInput (desde iOS 5), por lo que puede utilizar estos métodos para su instancia UITextView.

Va a ser algo como esto.

UITextRange * selectionRange = [textView selectedTextRange]; 
CGRect selectionStartRect = [textView caretRectForPosition:selectionRange.start]; 
CGRect selectionEndRect = [textView caretRectForPosition:selectionRange.end]; 
CGPoint selectionCenterPoint = (CGPoint){(selectionStartRect.origin.x + selectionEndRect.origin.x)/2,(selectionStartRect.origin.y + selectionStartRect.size.height/2)}; 

EDIT: Dado que el código de muestra se volvió un poco difícil de conseguir, agregué una imagen para complementar.

An image that illustrates what local variables represent

+0

Pequeño problema, lo llama punto central pero en realidad está calculando el punto inferior derecho. – Till

+0

@Sí, sí, originalmente pensé que [UITextInput caretRectForPosition:] tomará UITextRange como entrada, pero (como su nombre indica) realmente toma UITextPosition. Repare el código de muestra, y creo que ahora es más preciso, aunque un poco más difícil de conseguir. Y gracias por la edición! – barley

+0

Todavía tiene un pequeño problema en el cálculo de su centro: D ... compruebe la coordenada X de nuevo, los corchetes se configuran incorrectamente para calcular el centro. – Till

19

Hay algunas situaciones en las que la respuesta de la cebada no dará realmente el centro de la selección. Por ejemplo:

Screenshot showing an example of where using the caret rects would not be accurate

En este caso se puede ver el menú Copiar/Pegar está exhibiendo en el centro de la selección, que se extiende por todo el ancho del campo de texto. Pero calcular el centro de las dos rectas de careteo daría una posición mucho más hacia la derecha.

Usted puede obtener un resultado más preciso utilizando selectionRectsForRange:

UITextRange *selectionRange = [textView selectedTextRange]; 
NSArray *selectionRects = [self.textView selectionRectsForRange:selectionRange]; 
CGRect completeRect = CGRectNull; 
for (UITextSelectionRect *selectionRect in selectionRects) { 
    if (CGRectIsNull(completeRect)) { 
     completeRect = selectionRect.rect; 
    } else completeRect = CGRectUnion(completeRect,selectionRect.rect); 
} 

También vale la pena aclarar que si todavía está apoyando IOS 4 y el uso de cualquiera de estas respuestas, tendrá que asegurarse de que estos métodos son compatible antes de llamarlos: if ([textView respondsToSelector:@selector(selectedTextRange)]) { …

+0

Perfecto, funcionó como un encanto – aryaxt

+2

En realidad, no necesita el cheque para CGRectIsNull ya que CGRectUnion ya se encarga de esto. Según la documentación para CGRectUnion: "Si cualquiera de los rectángulos es un rectángulo nulo, se devuelve una copia del otro rectángulo" –

Cuestiones relacionadas