use separate caches for scaleAspectFill
This commit was merged in pull request #13.
This commit is contained in:
@@ -689,8 +689,6 @@ class ViewController: UIViewController, UIGestureRecognizerDelegate {
|
||||
var offset = scrollingCollectionView.contentOffset
|
||||
offset.y *= (screenSize.width / screenSize.height)
|
||||
scrollingCollectionView.setContentOffset(offset, animated: false)
|
||||
// FIXME: This is a caching issue, needs a different cache for scrolling since it Fill instead of Fit.
|
||||
scrollingCollectionView.reloadData()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1569,16 +1567,20 @@ enum Rotation {
|
||||
}
|
||||
|
||||
class ImageLoader {
|
||||
private let cache = NSCache<NSString, UIImage>()
|
||||
private let horCache = NSCache<NSString, UIImage>()
|
||||
private let portraitFitCache = NSCache<NSString, UIImage>()
|
||||
private let landscapeFitCache = NSCache<NSString, UIImage>()
|
||||
private let portraitFillCache = NSCache<NSString, UIImage>()
|
||||
private let landscapeFillCache = NSCache<NSString, UIImage>()
|
||||
private var loadingTasks: [String: (UIImage?) -> Void] = [:]
|
||||
private var activeTokens: [String: CancellationToken] = [:]
|
||||
private var archives = NSCache<NSString, Archive>()
|
||||
private let archives = NSCache<NSString, Archive>()
|
||||
|
||||
init() {
|
||||
// 128 MiB
|
||||
cache.totalCostLimit = 128 * 1024 * 1024
|
||||
horCache.totalCostLimit = 128 * 1024 * 1024
|
||||
portraitFitCache.totalCostLimit = 128 * 1024 * 1024
|
||||
landscapeFitCache.totalCostLimit = 128 * 1024 * 1024
|
||||
portraitFillCache.totalCostLimit = 128 * 1024 * 1024
|
||||
landscapeFillCache.totalCostLimit = 128 * 1024 * 1024
|
||||
// The reason archives are cached and have a strict limit of four, is because Archive supposedly opens a posix file pointer and keeps it until the object is destroyed.
|
||||
archives.countLimit = 4
|
||||
}
|
||||
@@ -1587,7 +1589,6 @@ class ImageLoader {
|
||||
loadImage(archiveURL: archiveURL, filename: filename, scaling: scaling, screenSize: screenSize, completion: nil)
|
||||
}
|
||||
|
||||
// FIXME: So scrolling is not really handled well in terms of caching. This is because it should have a separate cache since it uses a different scaling (Fill instead of Fit).
|
||||
func loadImage(
|
||||
archiveURL: URL, filename: String,
|
||||
scaling: UIView.ContentMode,
|
||||
@@ -1597,11 +1598,23 @@ class ImageLoader {
|
||||
let rotation: Rotation = screenSize.width > screenSize.height ? .horizontal : .vertical
|
||||
let key = filename
|
||||
|
||||
if rotation == .vertical, let cached = cache.object(forKey: key as NSString) {
|
||||
completion?(cached); return
|
||||
}
|
||||
if rotation == .horizontal, let cached = horCache.object(forKey: key as NSString) {
|
||||
completion?(cached); return
|
||||
if scaling == .scaleAspectFit {
|
||||
if rotation == .vertical, let cached = portraitFitCache.object(forKey: key as NSString) {
|
||||
completion?(cached); return
|
||||
}
|
||||
if rotation == .horizontal, let cached = landscapeFitCache.object(forKey: key as NSString) {
|
||||
completion?(cached); return
|
||||
}
|
||||
} else if scaling == .scaleAspectFill {
|
||||
if rotation == .vertical, let cached = portraitFillCache.object(forKey: key as NSString) {
|
||||
completion?(cached); return
|
||||
}
|
||||
if rotation == .horizontal, let cached = landscapeFillCache.object(forKey: key as NSString) {
|
||||
completion?(cached); return
|
||||
}
|
||||
} else {
|
||||
print("this should not be reachable")
|
||||
return
|
||||
}
|
||||
|
||||
if let existing = activeTokens[key], !existing.isCancelled {
|
||||
@@ -1662,8 +1675,14 @@ class ImageLoader {
|
||||
)
|
||||
let vScaledSize = aspectSize(for: image.size, in: vertical, scaling: scaling)
|
||||
let vScaleImage = resizeImage(image, to: vScaledSize)
|
||||
if let cost = imageByteSize(vScaleImage) {
|
||||
self.cache.setObject(vScaleImage, forKey: filename as NSString, cost: cost)
|
||||
let cost = imageByteSize(vScaleImage)!
|
||||
if scaling == .scaleAspectFit {
|
||||
self.portraitFitCache.setObject(vScaleImage, forKey: filename as NSString, cost: cost)
|
||||
} else if scaling == .scaleAspectFill {
|
||||
self.portraitFillCache.setObject(vScaleImage, forKey: filename as NSString, cost: cost)
|
||||
} else {
|
||||
print("this should be unreachable")
|
||||
return
|
||||
}
|
||||
if rotation == .vertical { image = vScaleImage }
|
||||
}
|
||||
@@ -1677,8 +1696,14 @@ class ImageLoader {
|
||||
)
|
||||
let hScaledSize = aspectSize(for: image.size, in: horizontal, scaling: scaling)
|
||||
let hScaleImage = resizeImage(image, to: hScaledSize)
|
||||
if let cost = imageByteSize(hScaleImage) {
|
||||
self.horCache.setObject(hScaleImage, forKey: filename as NSString, cost: cost)
|
||||
let cost = imageByteSize(hScaleImage)!
|
||||
if scaling == .scaleAspectFit {
|
||||
self.landscapeFitCache.setObject(hScaleImage, forKey: filename as NSString, cost: cost)
|
||||
} else if scaling == .scaleAspectFill {
|
||||
self.landscapeFillCache.setObject(hScaleImage, forKey: filename as NSString, cost: cost)
|
||||
} else {
|
||||
print("this should be unreachable")
|
||||
return
|
||||
}
|
||||
if rotation == .horizontal { image = hScaleImage }
|
||||
}
|
||||
@@ -1694,10 +1719,6 @@ class ImageLoader {
|
||||
loadingTasks[key] = nil
|
||||
}
|
||||
}
|
||||
|
||||
func imageIfLoaded(at path: String) -> UIImage? {
|
||||
return cache.object(forKey: path as NSString)
|
||||
}
|
||||
}
|
||||
|
||||
func imageByteSize(_ image: UIImage) -> Int? {
|
||||
|
||||
Reference in New Issue
Block a user