Swift中自定义UIView的加载时间

Swift中自定义UIView的加载时间

本文介绍了Swift中自定义UIView的加载时间很慢的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

背景

为了使文本视图水平滚动,我创建了一个自定义的UIView子类.该类将一个UITextView放入一个UIView中,旋转并翻转该视图,然后将该视图放入父UIView中.

In order to make a text view that scrolls horizontally for vertical Mongolian script, I made a custom UIView subclass. The class takes a UITextView, puts it in a UIView, rotates and flips that view, and then puts that view in a parent UIView.

旋转和翻转的目的是使文本垂直,并使换行正确.将所有内容粘贴在父UIView中的目的是使自动"布局可以在情节提要中使用. (请参见此处.)

The purpose for the rotation and flipping is so that the text will be vertical and so that line wrapping will work right. The purpose of sticking everything in a parent UIView is so that Auto layout will work in a storyboard. (See more details here.)

代码

我有一个可行的解决方案. github上的完整代码是此处 >,但是我创建了一个新项目,并剥离了所有我可以解决的不必要代码.以下代码仍然执行上述基本功能,但仍然存在以下所述的缓慢加载问题.

I got a working solution. The full code on github is here, but I created a new project and stripped out all the unnecessary code that I could in order to isolate the problem. The following code still performs the basic function described above but also still has the slow loading problem described below.

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的新手,所以我观看了有用的视频使用Xcode和Profiler调试内存问题时间分析器.

I noticed that the custom view loads very slowly. I'm new to Xcode Instruments so I watched the helpful videos Debugging Memory Issues with Xcode and Profiler and Time Profiler.

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

After that I tried finding the issue in my own project. It seems like no matter whether I use the Time Profiler or Leaks or Allocations tools, they all show that my class init method is doing too much work. (But I kind of knew that already from the slow load time before.) Here is a screen shot from the Allocations tool:

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

I didn't expand all of the call tree because it wouldn't have fit. Why are so many object being created? When I made a three layer custom view I knew that it wasn't ideal, but the number of layers that appears to be happening from the call tree is ridiculous. What am I doing wrong?

推荐答案

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

You shouldn't add or delete any subview inside layoutSubviews, as doing so triggers a call to layoutSubviews again.

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

Create your subview when you create your view, and then only adjust its position in layoutSubviews rather than deleting and re-adding it.

这篇关于Swift中自定义UIView的加载时间很慢的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-23 08:48