借用大型UIView占用大量内存

时间:2018-01-21 10:58:41

标签: ios swift uiview

当我开始绘制大型UIView(宽度:3700,高度:40000)时,需要大量内存 当应用程序启动时,内存为150 MB,当开始绘制时(调用setNeedsDisplay方法)大约需要1 GB,应用程序将崩溃

class DrawingVc: UIViewController {

    let  contentView = DrawableView()
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white

        contentView.translatesAutoresizingMaskIntoConstraints = false
        contentView.backgroundColor = .clear
        self.view.addSubview(contentView)
        contentView.frame = CGRect(x: 0, y: 0, width:view.frame.width,  height: 
        view.frame.height * 50)
 }

此处是自定义视图的代码,如您所见,setNeedsDisplaytouchMoves上运行

 class DrawableView: UIView {

    var mLastPath: UIBezierPath?
    weak var scdelegate: DrawableViewDelegate?
    var isDrawEnable = true

    private var drawingLines : [UIBezierPath] = []

    override init(frame: CGRect) {
        super.init(frame: frame)

    }

    required public init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

    }


    override func draw(_ rect: CGRect) {
        debugPrint("request draw")

        drawLine()

    }

    private func drawLine() {

        UIColor.blue.setStroke()
        for line in drawingList {
            line.lineWidth = 4
            line.stroke()
            line.lineCapStyle = .round
        }


    }

    var drawingList = [UIBezierPath]()
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        if touches.count == 2 {
            return
        }

        let location = (touches.first?.location(in: self))!
        mLastPath = UIBezierPath()
        mLastPath?.move(to: location)
        prevPoint = location

        drawingList.append(mLastPath!)
    }

        var prevPoint: CGPoint?
      var isFirst = true
    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {

    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        debugPrint("touchesMoved: " , (touches.first?.location(in: self).x)!  , (touches.first?.location(in: self).y)! )
        if let coalescedtouches =  event?.coalescedTouches(for: touches.first!)
        {
            for coalescedTouch in coalescedtouches
            {
                let locationInView = coalescedTouch.location(in: self)

                if let prevPoint = prevPoint {
                    let midPoint = CGPoint( x: (locationInView.x   + prevPoint.x) / 2, y: (locationInView.y + prevPoint.y) / 2)
                    if isFirst {
                        mLastPath?.addLine(to: midPoint)
                    }else {

                        mLastPath?.addQuadCurve(to: midPoint, controlPoint: prevPoint)
                    }
                    isFirst = false
                } else {
                    mLastPath?.move(to: locationInView)

                }
                prevPoint = locationInView
            }

        }
        setNeedsDisplay()
    }



}

是什么导致了这个问题以及如何解决这个问题?

1 个答案:

答案 0 :(得分:4)

您的视图大于iOS设备上可能的最大屏幕,因此我认为您的视图嵌入在滚动视图中。您应该只绘制视图的可见部分。不幸的是,insert()不直接支持此功能。您可以查看CATiledLayer,它仅支持绘制图层的可见部分,并且它也支持缩放图层的不同级别的细节。