Использовать внешнее изображение в UIImage imageNamed

Я загружаю два изображения из сети Apple.png и Apple@2x.png. Я хочу использовать [UIImage imageNamed:@"Apple.png"] поэтому он может использовать встроенные функции, чтобы определить, должен ли он отображать Apple.png или Apple@2x.png.

Где я могу хранить эти изображения? Я прочитал следующее в документации:

Название файла. Если изображение загружается впервые, метод ищет изображение с указанным именем в основном комплекте приложения.

Ах, так что основной комплект приложения - это путь. Вот как выглядит мой код:

NSString      *directory   = [[NSBundle mainBundle] bundlePath]; 
NSString      *path        = [directory stringByAppendingPathComponent:imageName];
NSFileManager *fileManager = [NSFileManager defaultManager];

[fileManager createFileAtPath:path contents:dataFetcher.receivedData attributes:nil];

Я проверил, был ли файл создан в папке пути, и это было правильно. Я также перетащил файл Example.png в файл своего проекта, чтобы посмотреть, хранится ли он в той же папке, и это тоже правильно.

Тем не мение, [UIImage imageNamed:@"Apple.png"], по-прежнему не удается получить изображения.

6 ответов

Вы не можете использовать UIImage+imageNamed: метод с фотографиями, загруженными приложением. Этот метод действительно ищет изображения в комплекте приложений, но вашему приложению не разрешается изменять свой собственный пакет во время выполнения.

Загрузите изображения (разумеется, асинхронно) в локальный магазин вашего приложения (т. Е. В свою песочницу) и сослаться на них локально. Вы можете использовать NSDocumentDirectory или же NSCachesDirectory всегда получать ссылку на их местоположение.

Создаются ли файлы с соответствующими разрешениями для доступа к ним? Вы удостоверились, что закрыли файл после сохранения?

Решение по ОП.

Категория для UIImage:

@implementation UIImage (ImageNamedExtension)

+ (UIImage *)imageNamed:(NSString *)name fromDirectory:(NSString *)directory {

    if ([UIScreen mainScreen].scale >= 3.0) {
        NSString *path3x = [directory stringByAppendingPathComponent:[[name stringByDeletingPathExtension] stringByAppendingFormat:@"@3x.%@", name.pathExtension]];
        UIImage *image = [UIImage imageWithContentsOfFile:path3x];
        if (image) {
            return image;
        }
    }
    if ([UIScreen mainScreen].scale >= 2.0) {
        NSString *path2x = [directory stringByAppendingPathComponent:[[name stringByDeletingPathExtension] stringByAppendingFormat:@"@2x.%@", name.pathExtension]];
        UIImage *image = [UIImage imageWithContentsOfFile:path2x];
        if (image) {
            return image;
        }
    }
    NSString *path = [directory stringByAppendingPathComponent:name];
    return [UIImage imageWithContentsOfFile:path];
}

@end

Я думаю, что лучшее решение - сделать в папке Library свой собственный пакет, например images.bundle, Там вы можете просматривать свои изображения для обоих разрешений. Для доступа к этим изображениям вы можете использовать pathForResource:ofType: метод класса NSBundle. Возвращает соответствующие изображения. Затем инициализируйте изображение с возвращенным путем.

NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error = nil;
NSURL *libraryURL = [fileManager URLForDirectory:NSLibraryDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:&error];
if (libraryURL == nil) {
    ALog(@"Could not access Library directory\n%@", [error localizedDescription]);
} else {
    NSURL *folderURL = [libraryURL URLByAppendingPathComponent:@"images.bundle"];
    DLog(@"Future bundle url = %@",folderURL);
    if (![fileManager createDirectoryAtURL:folderURL withIntermediateDirectories:YES attributes:nil error:&error]) {
        ALog(@"Could not create directory %@\n%@", [folderURL path], [error localizedDescription]);
    } else{
        NSBundle *bundle = [NSBundle bundleWithURL:folderURL];
        // put image and image@2x to the bundle;
        [bundle pathForResource:yourImageName ofType:@"png"];
    }
}

Вы не можете изменить свой пакет во время выполнения. я также думаю, что imageNamed использует что-то вроде карты ресурсов, инициализированной в приложении, содержащей ссылки на ресурсы пакета.

Попробуйте это вместо: http://atastypixel.com/blog/uiimage-resolution-independence-and-the-iphone-4s-retina-display/

Чао!

Другие вопросы по тегам