CATiledlayer

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)
    }
}
CATiledLayer 是一个可以用来加载和显示大尺寸瓦片地图的图层类。瓦片地图是一种将地图分割成许多小块(瓦片)并按需加载显示的技术。 CATiledLayer 在处理瓦片地图时具有很多优势。首先,它可以分割整个地图成许多小瓦片,这样只有在需要显示的时候才加载对应的瓦片,有效地节省了内存空间。其次,CATiledLayer 支持异步地加载瓦片,这意味着在瓦片加载过程中,用户仍然可以滑动和放大缩小地图而不会有明显的卡顿。此外,CATiledLayer 还可以自动处理瓦片的级别细节,即在放大和缩小地图时,会自动加载和卸载相应级别的瓦片,以提供更好的用户体验。 使用 CATiledLayer 加载瓦片地图的过程主要包括以下几个步骤。首先,我们需要将整个地图图片切割成许多小瓦片,并为每个瓦片创建一个对应的 CATiledLayer。然后,我们需要实现一个自定义的 UIView,并将其 layer 类型设置为 CATiledLayer。在自定义的 UIView 中,我们需要实现 drawRect 方法,在该方法中根据当前的可视区域,使用 CGContextDrawImage 方法将需要显示的瓦片绘制到屏幕上。此外,我们还需要实现一个自定义的 UIScrollView,用于处理地图的滑动和缩放,以及对应瓦片的加载和卸载。 总的来说,CATiledLayer 瓦片地图是一种高效加载和显示大尺寸地图的技术,它通过分割地图成小瓦片并按需加载显示,提供了更好的用户体验和内存效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值