Tiempo de carga lento para una UIView personalizada con la propiedad UITextView en Swift

Originalmente hice esta pregunta . Había asumido que el motivo del time de carga lenta de mi vista personalizada era el de capas múltiples vistas una encima de la otra o quizás debido a algún problema de recursion . Sin embargo, después de cortar más y más códigos para ver qué haría la diferencia, se UITextView si tenía un UITextView presente o no. Debido a que la fuente aparente de mi problema es tan diferente de lo que esperaba en mi primera pregunta, decidí comenzar una nueva pregunta en lugar de agregar una actualización larga a la anterior.

Configuré mi proyecto de testing con dos controlleres de vista. Un button en el primer controller de vista llama a un show segue al segundo controller de vista. El segundo controller de vista tiene mi vista personalizada en él. (Usando el segundo controller de vista, déjeme tener una idea de cuánto time tomó cargar la vista personalizada).

Código de vista personalizado:

 import UIKit @IBDesignable class UIMongolTextView: UIView { var textView = UITextView() // key line requinetworking init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } override init(frame: CGRect){ super.init(frame: frame) } } 

Como puede ver, la única diferencia de una UIView es que agregué una propiedad UITextView . Y es esta vista personalizada que se carga muy lentamente. Al ejecutar la herramienta Asignaciones en Instrumentos obtengo los siguientes resultados (un recuento de 997):

introduzca la descripción de la imagen aquí

Sin embargo, si comento la línea

  //var textView = UITextView() 

entonces, la vista personalizada se carga muy rápidamente y solo tiene un recuento de 7.

introduzca la descripción de la imagen aquí

¿Que esta pasando aqui? ¿Es posible usar una propiedad UITextView en una vista personalizada y evitar este lento time de carga?

Intenté algo similar donde una label y un campo de text se agregaron como subviews a una subclass de uiview. La forma en que lo hice fue la siguiente:

 @interface CustomTextField : UIView @property (weak, nonatomic) IBOutlet UITextField *valueField; @end 

Entonces, teníamos un file xib en el que realmente agregamos la label y el campo de text. En el file xib, el propietario del file es "CustomTextField" y las salidas están vinculadas con el file de encabezado desde allí.

El método del constructor se ve así:

 - (id)initWithValue:(NSString *)value { self = [super initWithFrame:CGRectZero]; if (self) { NSArray *nibs = [[NSBundle mainBundle] loadNibNamed:NSStringFromClass([self class]) owner:self options:nil]; UIView *view = nibs[0]; self.valueField.frame = view.bounds; [self setFrame:view.bounds]; [self addSubview:view]; [self.valueField setText:value]; } return self; } 

Funciona bien para mi

El cuello de botella es la propiedad selectable de su UITextView. Existe un problema de performance inexplicable en la creación de una UITextView con un set selectable en su valor pnetworkingeterminado de verdadero.

La forma más fácil de solucionar el problema es agregar la vista de text utilizando el guión gráfico, asegurándose de que desmarca la propiedad selectable . Parece que no hay una forma documentada de crear una vista de text no seleccionable en el código (ya que la configuration seleccionable como falsa después de la creación no evita el problema de performance durante la creación). Si necesita una vista de text seleccionable, primero cree una vista de text no seleccionable y luego establezca seleccionable en true en viewDidAppear .

Si no puede usar el guión gráfico, puede considerar utilizar una class de terceros como TTTAttributedLabel .

Parece que Apple usa una API privada para evitar este problema. Otros desarrolladores emprendedores han descubierto que, en ChatKit, las vistas de text parecen crearse usando un método privado llamado initReadonlyAndUnselectableWithFrame:textContainer:

descargó su código de github, ¿por qué no acaba de escribir una subclass de UITextView en lugar de UIView?

 // // UIMongolTextView-A.swift // Mongol App Componants // // Created by Allen Zhang on 12/13/15. // Copyright © 2015 MongolSuragch. All rights reserved. // import UIKit class UIMongolTextView_A: UITextView { override func awakeFromNib() { super.awakeFromNib() self.setup() } func setup() { // 1-10: ᠨᠢᠭᠡ ᠬᠤᠶᠠᠷ ᠭᠤᠷᠪᠠ ᠳᠦᠷᠪᠡ ᠲᠠᠪᠤ ᠵᠢᠷᠭᠤᠭ᠎ᠠ ᠳᠤᠯᠤᠭ᠎ᠠ ᠨᠠᠢ᠌ᠮᠠ ᠶᠢᠰᠦ ᠠᠷᠪᠠ self.transform = translateRotateFlip() } /* // Only override drawRect: if you perform custom drawing. // An empty implementation adversely affects performance during animation. override func drawRect(rect: CGRect) { // Drawing code } */ func translateRotateFlip() -> CGAffineTransform { var transform = CGAffineTransformIdentity // translate to new center transform = CGAffineTransformTranslate(transform, (self.bounds.width / 2)-(self.bounds.height / 2), (self.bounds.height / 2)-(self.bounds.width / 2)) // rotate counterclockwise around center transform = CGAffineTransformRotate(transform, CGFloat(-M_PI_2)) // flip vertically transform = CGAffineTransformScale(transform, -1, 1) return transform } } 

Tuve un problema de performance muy similar con UITextView, pero creo que la causa raíz y la solución fueron diferentes para mí.

Tenía una UITextView con text estático en un storyboard. No fue editable ni seleccionable. En un lento iPod Touch, el ViewController demoraría 5 segundos en cargarse.

Resulta que tenía un emoji en el text estático. ¡Cuando eliminé el emoji, el problema desapareció! Utilicé instrumentos para investigar lo que estaba sucediendo y unos 25 niveles en la huella en que se metía en un montón de … types de letra …. Estaba usando la fuente del sistema sin attributes, por lo que la primera idea que me vino a la mente fue el personaje de emoji en mi text.