背景
为了使垂直蒙古文脚本水平滚动的文本视图,我制作了一个自定义UIView
子类。该类接受 a UITextView
,将其放入 a UIView
,旋转并翻转该视图,然后将该视图放入 parentUIView
中。
旋转和翻转的目的是使文本垂直,从而使换行正常工作。将所有内容粘贴在父级中的目的UIView
是让自动布局可以在故事板中工作。(在此处查看更多详细信息。)
代码
我有一个可行的解决方案。github 上的完整代码在这里,但我创建了一个新项目并删除了所有我可以使用的不必要代码以隔离问题。下面的代码仍然执行上面描述的基本功能,但仍然存在下面描述的加载缓慢问题。
import UIKit
@IBDesignable class UIMongolTextView: UIView {
private var view = UITextView()
private var oldWidth: CGFloat = 0
private var oldHeight: CGFloat = 0
@IBInspectable var text: String {
get {
return view.text
}
set {
view.text = newValue
}
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override init(frame: CGRect){
super.init(frame: frame)
}
override func sizeThatFits(size: CGSize) -> CGSize {
// swap the length and width coming in and going out
let fitSize = view.sizeThatFits(CGSize(width: size.height, height: size.width))
return CGSize(width: fitSize.height, height: fitSize.width)
}
override func layoutSubviews() {
super.layoutSubviews()
// layoutSubviews gets called multiple times, only need it once
if self.frame.height == oldHeight && self.frame.width == oldWidth {
return
} else {
oldWidth = self.frame.width
oldHeight = self.frame.height
}
// Remove the old rotation view
if self.subviews.count > 0 {
self.subviews[0].removeFromSuperview()
}
// setup rotationView container
let rotationView = UIView()
rotationView.frame = CGRect(origin: CGPointZero, size: CGSize(width: self.bounds.height, height: self.bounds.width))
rotationView.userInteractionEnabled = true
self.addSubview(rotationView)
// transform rotationView (so that it covers the same frame as self)
rotationView.transform = translateRotateFlip()
// add view
view.frame = rotationView.bounds
rotationView.addSubview(view)
}
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
}
}
问题
我注意到自定义视图加载非常缓慢。我是 Xcode Instruments 的新手,所以我观看了有用的视频Debugging Memory Issues with Xcode and Profiler和Time Profiler。
之后,我尝试在自己的项目中找到问题。似乎无论我使用 Time Profiler 还是 Leaks 或 Allocations 工具,它们都表明我的类init
方法做了太多的工作。(但我从之前的缓慢加载时间就知道了。)这是分配工具的屏幕截图:
我没有展开所有的调用树,因为它不合适。为什么要创建这么多对象?当我制作一个三层自定义视图时,我知道它并不理想,但是调用树中似乎发生的层数是荒谬的。我究竟做错了什么?