UIImageView - Как получить имя файла изображения?

82

Можно ли прочитать имя, UIImageView's UIImage которое в настоящее время хранится в UIImageView?

Я надеялся, что вы сможете сделать что-то подобное, но не понял этого.

NSString *currentImageName = [MyIImageView getFileName];
Kuberchaun
источник

Ответы:

88

Нет. Вы не можете этого сделать.

Причина в том, что UIImageViewэкземпляр не хранит файл изображения. Он хранит отображение UIImageэкземпляра. Когда вы создаете изображение из файла, вы делаете что-то вроде этого:

UIImage *picture = [UIImage imageNamed:@"myFile.png"];

Как только это будет сделано, ссылка на имя файла исчезнет. ВUIImageЭкземпляр содержит данные, независимо от того, где он получил его. Таким образом, UIImageViewневозможно было узнать имя файла.

Кроме того, даже если бы вы могли, вы бы никогда не получили информацию о имени файла из представления. Это нарушает работу MVC.

Джонатан Стерлинг
источник
62
То, что он нарушает работу MVC, не означает, что вам не следует этого делать. В конце концов, правила предназначены для того, чтобы их нарушать;)
Sneakyness
10
Некоторые правила есть. Но на iPhone и Mac вы всегда должны делать все возможное, чтобы придерживаться MVC. Это самоуверенная среда.
Джонатан Стерлинг,
На самом деле это возможно, но для редактирования imageNamed: требуется прикрутить среду выполнения Objective-C (да, нарушая множество правил). Если вы действительно должны сделать это в своем проекте по какой-то важной причине, см. Мой ответ ниже.
Бен Готоу,
3
@JonathanSterling есть много разных интерпретаций MVC
abbood
Похоже, UIImage (named: String) в Swift
RedEagle2000
109

вы можете использовать метод setAccessibilityIdentifier для любого подкласса UIView

UIImageView *image ;
[image setAccessibilityIdentifier:@"file name"] ;

NSString *file_name = [image accessibilityIdentifier] ;
Низар Ахмед
источник
1
я наткнулся здесь просто b / c, я создаю приложение с локализованными изображениями ... и я хочу создать localizeметод, который просто просматривает изображения и выполняет регулярное выражение для имени изображения (у меня есть очень веские причины сделать эти изображения фактических изображений, а не создание пользовательского UIImage) .. мне было интересно, есть ли более чистый способ локализации изображений в объекте-c .. поскольку все говорят о MVC, а о чем нет
abbood
1
Я знаю, что с MVC не все в порядке, но мне это было нужно для тестирования.
Радек Вильчак
Для OSXaccessibilityDescription
Ануп Вайдья
есть ли у этого решения технический недостаток? это кажется самым простым и чистым решением, так почему же оно не считается принятым ответом?
Crashalot
19

Нет-нет-нет… в общем, такое возможно. Это просто заставит вас почувствовать себя грязным человеком. Если вам это абсолютно необходимо, сделайте следующее:

  • Создайте категорию с вашей собственной реализацией +imageNamed:(NSString*)imageNameэтого вызова существующей реализации и используйте описанный здесь метод ( как использовать objc_setAssociatedObject / objc_getAssociatedObject внутри объекта? ) Для постоянной связи imageNameс возвращаемым объектом UIImage.

  • Используйте метод Swizzling, чтобы заменить предоставленную реализацию imageNamed:для вашей реализации в таблице поиска методов среды выполнения Objective-C.

  • Получите доступ к имени, которое вы связали с экземпляром UIImage (используя objc_getAssociatedObject), в любое время, когда захотите.

Я могу проверить, что это работает, с оговоркой, что вы не можете получить имена UIImage, загруженные в NIB. Похоже, что изображения, загруженные из NIB, не создаются с помощью каких-либо стандартных вызовов функций, поэтому для меня это действительно загадка.

Я оставляю реализацию на ваше усмотрение. Копирование и вставка кода, связанного со средой выполнения Objective-C, - очень плохая идея, поэтому хорошо подумайте о потребностях вашего проекта и реализуйте это только в случае необходимости.

Бен Готоу
источник
1
Почему бы вам просто не создать подкласс UIImageдля переопределения метода?
vrwim
vrwim: вам нужно swizzle, когда вы хотите что-то добавить к существующему поведению. если вы будете использовать категорию (или наследование), вы сможете переключить один код на другой, но вы не сможете сделать это без потери исходного поведения. другими словами, если вы попытаетесь написать (в унаследованном классе): +imageNamed:(NSString*)imageName { // save file name in new property or whatever [self imageNamed:imageName]; // infinite loop [super imageNamed:imageName]; // super doesn't contain such a method }
yonivav
привет, есть ли причина не просто использовать setAccessibilityIdentifier, как это предложил низар ахмед?
Crashalot
10

Нет собственного способа сделать это; однако вы можете легко создать такое поведение самостоятельно.

Вы можете UIImageViewсоздать подкласс и добавить новую переменную экземпляра:

NSString* imageFileName;

Затем вы можете переопределить setImage, сначала установив imageFileNameимя файла изображения, которое вы устанавливаете, а затем позвоните [super setImage:imageFileName]. Что-то вроде этого:

-(void) setImage:(NSString*)fileName
{
   imageFileName = fileName;
   [super setImage:fileName];
}

То, что это невозможно сделать изначально, не означает, что это невозможно :)

ВендиКидд
источник
Спасибо, что переместили это и помогли содержать сайт в чистоте!
ао
10
if ([imageForCheckMark.image isEqual:[UIImage imageNamed:@"crossCheckMark.png"]]||[imageForCheckMark.image isEqual:[UIImage imageNamed:@"checkMark.png"]])
{

}
Эйнштейн
источник
В условии, что я только что проверяю имя изображений
iEinstein
2
Ответы только на код не так полезны. Добавьте короткий текст, объясняющий, что делает ваш фрагмент кода.
nalply
если условие совпадает с именем изображения в imageForCheckMark и [UIImage imageNamed: @ "crossCheckMark.png"]], если истинно, то выполнить некоторую строку кода, иначе другую строку кода
iEinstein
Это как сказать нам, если изображение hot dogили not hotdog.
ScottyBlades
Я создаю несколько модульных тестов, чтобы проверить, установлены ли правильные изображения, для меня это полезно.
MQoder
9

Нет. Нет возможности сделать это изначально. Вам нужно будет создать подкласс UIImageView и добавить свойство imageFileName (которое вы устанавливаете при установке изображения).

Кенни Винкер
источник
привет, Кенни, есть ли причина не просто использовать setAccessibilityIdentifier, как это предлагает низар Ахмед?
Crashalot
7

Ни UIImageView, ни UIImage не хранят имя файла загруженного изображения.

Вы также можете

1: (как было предложено Кенни Винкером выше) подкласс UIImageView, чтобы иметь свойство fileName или

2: назовите файлы изображений номерами (image1.jpg, image2.jpg и т. Д.) И пометьте эти изображения соответствующим номером (tag = 1 для image1.jpg, tag = 2 для image2.jpg и т. Д.) Или

3: иметь переменную уровня класса (например, NSString * currentFileName), которая обновляется всякий раз, когда вы обновляете изображение UIImageView.

Михир Матурия
источник
3

Этот код поможет вам: -

- (NSString *)getFileName:(UIImageView *)imgView{
    NSString *imgName = [imgView image].accessibilityIdentifier;
    NSLog(@"%@",imgName);
    return imgName;
}

Используйте это как: -

NSString *currentImageName = [self getFileName:MyIImageView];
Джунаидсидху
источник
Он вернет null, потому что вы еще не установили accessibilityIdentifier. Задайте его так, [image setAccessibilityIdentifier:@"demoFileName.png"] ;а затем вызовите этот метод
NSNoob
Консоль сообщает: ошибка: свойство 'accessibilityIdentifier' не найдено в объекте типа 'UIImage *' - Xcode 8.1
Джамал Зафар
Возвращает Null, не пытайтесь это сделать
Кингсли Митчелл
в любом случае он возвращает null
Саранджит
3

Или вы можете использовать идентификатор восстановления, например:

let myImageView = UIImageView()
myImageView.image = UIImage(named: "anyImage")
myImageView.restorationIdentifier = "anyImage" // Same name as image's name!

// Later, in UI Tests:
print(myImageView.restorationIdentifier!) // Prints "anyImage"

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

myImageView.restorationIdentifier = "newImageName"

Надеюсь, это вам поможет, удачи!

ThiagoAM
источник
2

Да, вы можете сравнить с помощью данных, как показано ниже.

UITableViewCell *cell = (UITableViewCell*)[self.view viewWithTag:indexPath.row + 100];

UIImage *secondImage = [UIImage imageNamed:@"boxhover.png"];

NSData *imgData1 = UIImagePNGRepresentation(cell.imageView.image);
NSData *imgData2 = UIImagePNGRepresentation(secondImage);

BOOL isCompare =  [imgData1 isEqual:imgData2];
if(isCompare)
{
    //contain same image
    cell.imageView.image = [UIImage imageNamed:@"box.png"];
}
else
{
    //does not contain same image
    cell.imageView.image = secondImage;
}
Хардик Мамтора
источник
2

Вы можете использовать функцию времени выполнения объекта c для связывания имени изображения с UImageView.

Первый импорт #import <objc/runtime.h> в вашем классе

затем реализуйте свой код, как показано ниже:

NSString *filename = @"exampleImage";
UIImage *image = [UIImage imagedName:filename];
objc_setAssociatedObject(image, "imageFilename", filename, OBJC_ASSOCIATION_COPY);
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
//You can then get the image later:
NSString *filename = objc_getAssociatedObject(imageView, "imageFilename");

Надеюсь, это поможет тебе.

Нишант Тяги
источник
2

Получить имя изображения Swift 4.2

Есть способ сравнить названия изображений кнопок, которые есть в активах.

@IBOutlet weak var extraShotCheckbox: UIButton!

@IBAction func extraShotCheckBoxAction(_ sender: Any) {
    extraShotCheckbox.setImage(changeCheckBoxImage(button: extraShotCheckbox), for: .normal)
}

func changeCheckBoxImage(button: UIButton) -> UIImage {
    if let imageView = button.imageView, let image = imageView.image {
        if image == UIImage(named: "checkboxGrayOn") {
            return UIImage(named: "checkbox")!
        } else {
            return UIImage(named: "checkboxGrayOn")!
        }
    }
    return UIImage()
}
Doci
источник
1

Swift 3

Сначала установите accessibilityIdentifier как imageName.

myImageView.image?.accessibilityIdentifier = "add-image"

Затем используйте следующий код.

extension UIImageView
{
func getFileName() -> String? {
    // First set accessibilityIdentifier of image before calling.
    let imgName = self.image?.accessibilityIdentifier
    return imgName
}
}

Наконец, вызывающий способ идентификации

myImageView.getFileName()
Абдул Хамид
источник
0

Я справился с этой проблемой, я решил ее с помощью шаблона проектирования MVC, я создал класс Card:

@interface Card : NSObject

@property (strong,nonatomic) UIImage* img;

@property  (strong,nonatomic) NSString* url;

@end

// затем UIViewControllerв DidLoadметоде выполнения:

// init Cards
Card* card10= [[Card alloc]init];
card10.url=@"image.jpg";  
card10.img = [UIImage imageNamed:[card10 url]];

// например

UIImageView * myImageView = [[UIImageView alloc]initWithImage:card10.img];
[self.view addSubview:myImageView];

// вы можете проверить имя изображения, чтобы вы могли сделать это:

//например

 NSString * str = @"image.jpg";

 if([str isEqualToString: [card10 url]]){
 // your code here
 }
Хасан Саваед
источник
-1

используйте ниже

 UIImageView *imageView = ((UIImageView *)(barButtonItem.customView.subviews.lastObject));
 file_name = imageView.accessibilityLabel;
Рамо
источник
-1

Код работает в swift3 - напишите код внутри метода делегата didFinishPickingMediaWithInfo:

if let referenceUrl = info[UIImagePickerControllerReferenceURL] as? 

NSURL {

  ALAssetsLibrary().asset(for: referenceUrl as URL!, resultBlock: { asset in

    let fileName = asset?.defaultRepresentation().filename()
    print(fileName!)

    //do whatever with your file name            
    }, failureBlock: nil)
}
Нирадж Пол
источник