Доступ к каталогу активов pathForResource
Похоже, что:
[[NSBundle mainBundle] pathForResource:@"name" ofType:@"png"];
Ничего не возвращает для ресурсов, которые находятся в каталоге ресурсов Images.xcassets. Я также попробовал:
[[NSBundle mainBundle] pathForResource:@"name" ofType:@"png" inDirectory:@"Images"];
[[NSBundle mainBundle] pathForResource:@"name" ofType:@"png" inDirectory:@"Images.xcassets"];
Но ни один из них не сработал.
У кого-нибудь был успех в поиске путей к ресурсам в каталоге?
6 ответов
Та же проблема, но я не думаю, что мы могли бы получить к нему доступ через pathForResource:
, кроме ниже:
UIImage* image = [UIImage imageNamed:@"name-in-asset-catalog"];
Это было четко задокументировано:
Каждый набор в каталоге активов имеет имя. Вы можете использовать это имя для программной загрузки любого отдельного изображения, содержащегося в наборе. Чтобы загрузить изображение, вызовите метод UIImage:imageNamed:, передав имя набора, который содержит изображение.
Я обнаружил, что в пакете с компилированным приложением вышел файл с именем "Assets.car", и я думаю, что это все наборы изображений в моем проекте, и они должны были быть заархивированы или что-то еще.
Обратитесь к документации Apple:
Xcode 5 предоставляет различные функциональные возможности для каталогов активов в зависимости от цели развертывания для вашего проекта:
- Для всех проектов отдельные изображения могут быть загружены с использованием заданных имен.
- Для проектов с целью развертывания iOS 7 XCode компилирует ваши каталоги ресурсов в исполняемый двоичный формат файла, который сокращает время загрузки вашего приложения.
Итак, это все.
Я также ищу способ, который не использует imageNamed:
Я не хочу, чтобы время выполнения кэшировало мои изображения.
Я хотел получить доступ к некоторым векторным ресурсам для создания UNNotificationAttachment
с местными ресурсами, поэтому я придумал этот вспомогательный класс. Он просто получает изображение из ресурсов, сохраняет свои данные на диск и возвращает URL файла. Я надеюсь, что это помогает кому-то.
import UIKit
class AssetExtractor {
static func createLocalUrl(forImageNamed name: String) -> URL? {
let fileManager = FileManager.default
let cacheDirectory = fileManager.urls(for: .cachesDirectory, in: .userDomainMask)[0]
let url = cacheDirectory.appendingPathComponent("\(name).png")
guard fileManager.fileExists(atPath: url.path) else {
guard
let image = UIImage(named: name),
let data = UIImagePNGRepresentation(image)
else { return nil }
fileManager.createFile(atPath: url.path, contents: data, attributes: nil)
return url
}
return url
}
}
[UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"%@/%@.png", [[NSBundle mainBundle] resourcePath], imgName]];
imgName: имя набора изображений, безразличное истинное имя изображения в наборе изображений.
Попробуйте использовать имя изображения, как определено в шаге "Компиляция каталога ресурсов". Вы найдете это в результатах сборки. Обязательно расшифруйте стенограмму - вы должны увидеть что-то вроде этого:
/* com.apple.actool.compilation-results */
/path/to/Debug-iphonesimulator/Your.app/LaunchImage-800-Portrait-736h@3x.png
/path/to/Debug-iphonesimulator/Your.app/LaunchImage-800-667h@2x.png
/path/to/Debug-iphonesimulator/Your.app/LaunchImage-700@2x.png
/path/to/Debug-iphonesimulator/Your.app/LaunchImage-700-568h@2x.png
/path/to/Debug-iphonesimulator/Your.app/LaunchImage-700-Landscape~ipad.png
/path/to/Debug-iphonesimulator/Your.app/LaunchImage-700-Landscape@2x~ipad.png
Протестировано с использованием +[UIImage imageNamed:]
с Xcode 6.1.1.
Хотя существует файл Contents.json (см. Ниже), связанный с каждым элементом в xcassets, который содержит имена файлов изображений этого элемента, он, по-видимому, недоступен на уровне файловой системы. Все изображения помещаются в одну папку файловой системы после компиляции. Файл json генерируется автоматически и не должен редактироваться, но он предоставляет шаблон для обходного пути.
Назовите каждый файл с единообразным суффиксом, чтобы он соответствовал идиоме, масштабу и подтипу, присутствующим в файле json. Это требует ручной работы, выбрав опцию "Показать в Finder" для каждого актива и переименовав каждый файл, но после завершения вы можете использовать pathForResource в сочетании с функцией, чтобы добавить соответствующий суффикс к имени базового актива, чтобы получить соответственно- размер изображения.
Пример кода для получения пути:
NSString *imageName = @"Add to Cart";
NSString *imageSuffix = [self someMethodThatDeterminesSuffix]; // Example: "-iphone-2x-retina4"
NSString *imagePath = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"%@%@", imageName, imageSuffix] ofType:@"png"];
Пример файла Contents.json для актива изображения "Добавить в корзину":
{
"images" : [
{
"idiom" : "iphone",
"scale" : "1x",
"filename" : "Add to Cart-iphone-1x.png"
},
{
"idiom" : "iphone",
"scale" : "2x",
"filename" : "Add to Cart-iphone-2x.png"
},
{
"idiom" : "iphone",
"filename" : "Add to Cart-iphone-2x-retina4.png",
"subtype" : "retina4",
"scale" : "2x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
В частности, для изображений запуска и значков приложений пути к изображениям доступны через ключи UILaunchImages и CFBundleIcons Info.plist соответственно. Похоже, что эти изображения генерируются индивидуально, а значения Info.plist обновляются во время сборки приложения при использовании каталогов ресурсов (и если нет, то эти ключи записываются непосредственно в пользовательский интерфейс Xcode). Возможно, вам придется написать некоторый код, чтобы определить правильный подсловарь для использования, но изображения доступны отдельно, и в этом случае вы можете избежать использования imageNamed.