使用UITextView属性在Swift中自定义UIView的加载时间较慢

我最初问这个问题 。 我曾经假设,我的自定义视图的加载时间很慢的原因是因为将多个视图层叠在一起,或者可能是由于某种recursion问题 。 但是,在截取越来越多的代码之后,看看有什么不同之处,最后是我是否有UITextView存在。 由于我的问题的明显根源与我在第一个问题中所期待的完全不同,因此我决定提出一个新的问题,而不是对旧问题进行冗长的更新。

我用两个视图控制器设置我的testing项目。 第一个视图控制器上的一个button调用show segue到第二个视图控制器。 第二个视图控制器上有我的自定义视图。 (使用第二个视图控制器让我了解加载自定义视图需要多长时间。)

自定义查看代码:

 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) } } 

正如你所看到的,与UIView的唯一区别是我添加了一个UITextView属性。 这是自定义视图加载非常缓慢。 在仪器中运行分配工具我得到以下结果(计数为997):

在这里输入图像说明

但是,如果我注释掉这一行

  //var textView = UITextView() 

那么我自定义视图加载速度非常快,只有7的计数。

在这里输入图像说明

这里发生了什么? 是否有可能在自定义视图中使用UITextView属性,并避免这种缓慢的加载时间?

尝试了类似的地方,标签和文本字段被添加为uiview子类的子视图。 我做的是这样的:

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

所以,我们有一个xib文件,我们实际上添加了标签和文本字段。 在xib文件中,文件的所有者是“CustomTextField”,并且出口与从那里的头文件链接。

构造函数的方法如下所示:

 - (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; } 

为我工作得很好。

瓶颈是你的UITextView的selectable属性。 在创buildUITextView时有一个莫名其妙的性能问题, selectable将其设置为默认值true。

解决这个问题的最简单的方法是使用故事板添加文本视图,确保您取消selectable属性。 似乎没有书面的方法来在代码中创build一个不可select的文本视图(因为在创build之后将设置select为false并不能避免创build过程中的性能问题)。 如果您需要可选的文本视图,请首先创build一个不可选的文本视图,然后在viewDidAppear中将可选项设置为true。

如果你不能使用故事板,你可能要考虑使用第三方类,如TTTAttributedLabel 。

它看起来像苹果使用私人API来避免这个问题。 其他进取的开发人员发现 ,在ChatKit中,文本视图似乎是使用名为initReadonlyAndUnselectableWithFrame:textContainer:的私有方法创build的initReadonlyAndUnselectableWithFrame:textContainer:

从github下载你的代码,你为什么不写一个UITextView的子类而不是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 } } 

我有一个UITextView非常类似的性能问题,但我认为根本原因和解决scheme对我来说是不同的。

我有一个故事板上的静态文本的UITextView。 这是不可编辑或可选的。 在缓慢的iPod触摸ViewController将需要5秒加载。

原来,我在静态文本中有一个表情符号。 当我删除表情符号时,问题就消失了! 我使用工具来深入了解正在发生的事情,大约25层深的痕迹,它是进入一堆字体…方法。 我使用的是没有属性的系统字体,所以想到的第一个想法是我的文本中的表情符号字符。