CATiledlayer

来源:互联网 发布:陈子豪cf手游刷枪软件 编辑:程序博客网 时间:2024/06/15 19:41

CATiledLayer

功能简介

  • CATiledLayer以图块(tile)为单位异步绘制图层内容,对超大尺寸图片或者只能在视图中显示一小部分的内容效果拔群,因为不用把内容完全载入内存就可以看到内容。
  • 把内容分解成固定大小的tile,当图块在屏幕上显示的时候,它会调用drawRect的方法进行绘制,只有可见的图块才绘制,这样就节约了处理时间和内存。

相关属性

  • 产生模糊的根源是图层的细节层次(level of detail,简称LOD),CATiledLayer有两个相关属性:

  • levelsOfDetail:指图层维护的LOD数目,默认值为1,每进一级会对前一级分辨率的一半进行缓存,图层的levelsOfDetail最大值,也就是最底层细节,对应至少一个像素点。

  • levelsOfDetailBias:指的是该图层缓存的放大LOD数目,默认为0,即不会额外缓存放大层次,每进一级会对前一级两倍分辨率进行缓存。

处理绘制有几种方法:

    import UIKit    class TiledBackgroundView: UIView {    let sideLength = CGFloat(50.0)    //重写layerClass(),令该视图创建的图层实例为CATiledLayer    override class func layerClass() -> AnyClass {        return CATiledLayer.self    }    required init(coder aDecoder: NSCoder) {        super.init(coder: aDecoder)        srand48(Int(NSDate().timeIntervalSince1970))        //CATiledLayer类型转换        let layer = self.layer as CATiledLayer        //缩放图层内容        let scale = UIScreen.mainScreen().scale        //适应屏幕        layer.contentsScale = scale        //设置图块尺寸        layer.tileSize = CGSize(width: sideLength * scale, height:          sideLength * scale)    }    override func drawRect(rect: CGRect) {        let context = UIGraphicsGetCurrentContext()        var red = CGFloat(drand48())        var green = CGFloat(drand48())        var blue = CGFloat(drand48())        //以随机色块填充视图。        CGContextSetRGBFillColor(context, red, green, blue, 1.0)        CGContextFillRect(context, rect)        }    }

分块绘制

    class TilingViewForImage: UIView {    //创建属性,分别是图块边长、原图文件名、供TileCutter扩展保存图块的缓存文件夹路径。    let sideLength = CGFloat(640.0)    let fileName = "windingRoad"    let cachesPath = NSSearchPathForDirectoriesInDomains(.CachesDirectory, .UserDomainMask, true)[0] as String    override class func layerClass() -> AnyClass {        return CATiledLayer.self        }        required init(coder aDecoder: NSCoder) {            super.init(coder: aDecoder)        //把视图的图层转换为分块图层        let layer = self.layer as CATiledLayer        //设置图块大小        layer.tileSize = CGSize(width: sideLength, height: sideLength)        注意此处不必设置contentsScale适配屏幕,因为是直接修改视图自身的图层,而不是手动创建子图层        }           override func drawRect(rect: CGRect) {        //按行列绘制各个图块        let firstColumn = Int(CGRectGetMinX(rect) / sideLength)        let lastColumn = Int(CGRectGetMaxX(rect) / sideLength)        let firstRow = Int(CGRectGetMinY(rect) / sideLength)        let lastRow = Int(CGRectGetMaxY(rect) / sideLength)        for row in firstRow...lastRow {            for column in firstColumn...lastColumn {                if let tile = imageForTileAtColumn(column, row: row) {      let x = sideLength * CGFloat(column)      let y = sideLength * CGFloat(row)      let point = CGPoint(x: x, y: y)      let size = CGSize(width: sideLength, height: sideLength)      var tileRect = CGRect(origin: point, size: size)      tileRect = CGRectIntersection(bounds, tileRect)      tile.drawInRect(tileRect)    }  }}}func imageForTileAtColumn(column: Int, row: Int) -> UIImage? {    let filePath = "\(cachesPath)/\(fileName)_\(column)_\(row)"    return UIImage(contentsOfFile: filePath)    }}
0 0