繁体   English   中英

Swift中自定义UIView的加载时间慢

[英]Slow load time for custom UIView in Swift

背景

为了使文本视图可以水平滚动以显示垂直的蒙古文脚本 ,我制作了一个自定义UIView子类。 该类接受一个UITextView ,将其放入UIView ,旋转和翻转该视图,然后将该视图放入父UIView

在此处输入图片说明

旋转和翻转的目的是使文本垂直,使换行正确。 将所有内容粘贴在父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的新手,所以我观看了有用的视频: Xcode和ProfilerTime Profiler的“ 调试内存问题

之后,我尝试在自己的项目中查找问题。 似乎无论我使用Time Profiler还是Leaks或Allocations工具,它们都表明我的类init方法执行了太多工作。 (但是我以前从缓慢的加载时间就已经知道了。)这是“分配”工具的屏幕截图:

在此处输入图片说明

我没有扩展所有的调用树,因为它不合适。 为什么要创建这么多对象? 当我创建一个三层的自定义视图时,我知道它不是理想的,但是在调用树中似乎正在发生的层数太可笑了。 我究竟做错了什么?

您不应在layoutSubviews内部添加或删除任何子视图,因为这样做会再次触发对layoutSubviews的调用。

创建视图时创建子视图,然后仅调整其在layoutSubviews位置,而不是删除并重新添加它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM