ios swift performance uitextview custom-view

ios - Tiempo de carga lento para UIView personalizado con la propiedad UITextView en Swift



performance custom-view (4)

Originalmente hice esta pregunta . Había asumido que la razón del lento tiempo de carga de mi vista personalizada era el hecho de colocar varias vistas una encima de la otra o quizás debido a algún problema de recursión . Sin embargo, después de eliminar cada vez más código para ver qué marcaría la diferencia, todo se reducía a 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 prueba con dos controladores de vista. Un botón en el primer controlador de vista llama a un show segue al segundo controlador de vista. El segundo controlador de vista tiene mi vista personalizada en él. (El uso del segundo controlador de vista me permite tener una idea de cuánto tardó en cargar la vista personalizada).

Código de vista personalizado:

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

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

Sin embargo, si comento la línea

//var textView = UITextView()

Luego, la vista personalizada se carga muy rápidamente y solo cuenta con 7.

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


El cuello de botella es la propiedad selectable de su UITextView. Hay un problema de rendimiento inexplicable en la creación de un UITextView con un conjunto selectable a su valor predeterminado verdadero.

La forma más fácil de solucionar el problema es agregar su vista de texto usando 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 texto no seleccionable en el código (como la configuración seleccionable en falso después de la creación no evita el problema de rendimiento durante la creación). Si necesita una vista de texto seleccionable, primero cree una vista de texto no seleccionable, y luego establezca seleccionable en verdadero en viewDidAppear .

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

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


Intentó algo similar donde se agregaron una etiqueta y un campo de texto como subvistas a una subclase uiview. La forma en que lo hice fue la siguiente:

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

Entonces, tuvimos un archivo xib en el que agregamos la etiqueta y el campo de texto. En el archivo xib, el propietario del archivo es "CustomTextField" y las salidas están vinculadas con el archivo de encabezado desde allí.

El método 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


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

Tenía un UITextView con texto estático en un guión gráfico. No fue editable ni seleccionable. En un iPod Touch lento, el ViewController tardaría 5 segundos en cargarse.

Resulta que tenía un emoji en el texto estático. Cuando quité el emoji el problema desapareció! Utilicé instrumentos para profundizar en lo que estaba sucediendo y unos 25 niveles de profundidad en el rastro que estaba recibiendo en un montón de ... fuentes ... métodos. Estaba usando la fuente del sistema sin atributos, por lo que la primera idea que me vino a la mente fue el carácter emoji en mi texto.


descargó su código de github, ¿por qué no escribe una subclase 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 } }