簡體   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