UIImage using contentsOfFile

Я использую

self.imageView.image = UIImage(named: "foo.png")

для выбора и загрузки изображений в UIIMageView. У меня есть изображения в приложении под images.xcassets. Проблема в том, что этот конкретный init кэширует изображение для повторного использования в соответствии с официальной документацией Apple :

Если у вас есть файл изображения, который будет отображаться только один раз и убедитесь, что он не добавляется в системный кеш, вы должны вместо этого создайте свое изображение, используя imageWithContentsOfFile:. Это будет сохранить одноразовый образ из кеша системы, потенциально улучшая характеристики использования памяти вашего приложения.

Мое представление позволяет циклически перемещаться по изображениям, прежде чем выбирать их, и поэтому объем памяти увеличивается, когда я перехожу на велосипед и никогда не спускаюсь, даже когда я перехожу назад с этого вида.

Поэтому я пытаюсь использовать UIIMage(contentsOfFile: "path to the file"), который не кэширует изображение. Здесь у меня возникают проблемы с программным получением пути к изображениям, которые я сохранил в images.xcassets.

Я попытался использовать:

NSBundle.mainBundle().resourcePath
и
NSBundle.mainBundle().pathForResource("foo", ofType: "png")

без везения. Для первого я получаю resourcePath, но при доступе к нему через терминал я не вижу никаких объектов изображения под ним, а второй получаю nil, когда я его использую. Есть ли простой способ сделать это?

Также рассмотрел несколько вопросов SO (например this, this и this) без везения. Должен ли я помещать свои изображения в другое место, чтобы иметь возможность использовать pathForResource()? Каков правильный путь?

Трудно представить, что никто не сталкивался с этим сценарием раньше:)!

Ответ 1

Если вам нужно использовать pathForResource(), чтобы избежать кэширования изображений, невозможно работать с images.xcassets. В этом случае вам нужно создать группу в XCode и добавить туда изображение (убедитесь, что это изображение скопировано в Copy Bundle Resources). После этого просто напишите:

Swift 5:

let bundlePath = Bundle.main.path(forResource: "imageName", ofType: "jpg")
let image = UIImage(contentsOfFile: bundlePath!)

Старый Свифт:

let bundlePath = NSBundle.mainBundle().pathForResource("imageName", ofType: "jpg") 
let image = UIImage(contentsOfFile: bundlePath!) 

Ответ 2

import Foundation
import UIKit

enum UIImageType: String {
    case PNG = "png"
    case JPG = "jpg"
    case JPEG = "jpeg"
}

extension UIImage {

    convenience init?(contentsOfFile name: String, ofType: UIImageType) {
        guard let bundlePath = Bundle.main.path(forResource: name, ofType: ofType.rawValue) else {
            return nil
        }
        self.init(contentsOfFile: bundlePath)!
    }

}

Использование:

let imageView.image = UIImage(contentsOfFile: "Background", ofType: .JPG)

Ответ 3

Когда вы реализуете массив изображений из ресурса группы изображений, вы можете загружать каждое изображение (скажем, b1, b2, b3, b4, b5) как

var imageIndex = 0
lazy var imageList = ["b1","b2","b3","b4","b5"]
let imagePath = Bundle.main.path(forResource: imageList[imageIndex], ofType: "jpg")
imageview.image = UIImage(contentsOfFile: imagePath!)