UIImageView - Як отримати ім'я файлу призначеного зображення?


82

Чи можна прочитати ім'я файлу, UIImageView's UIImage який зараз зберігається вUIImageView ?

Я сподівався, що ти зможеш зробити щось подібне, але не зрозумів цього.

NSString *currentImageName = [MyIImageView getFileName];

Відповіді:


88

Ні. Ви не можете цього зробити.

Причина полягає в тому, що UIImageViewекземпляр не зберігає файл зображення. Він зберігає UIImageекземпляр дисплеїв . Коли ви робите зображення з файлу, ви робите щось подібне:

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

Як тільки це буде зроблено, більше не буде посилання на ім'я файлу. UIImageПримірник містить дані, незалежно від того, де він отримав його. Таким чином, UIImageViewім'я файлу не міг знати.

Крім того, навіть якби ви могли, ви ніколи не отримаєте інформацію про ім'я файлу з подання. Це порушує MVC.


62
Те, що це порушує MVC, не означає, що ви не повинні цього робити. Зрештою, правила мають бути порушені;)
Підлість

10
Деякі правила є. Але на iPhone та Mac ви завжди повинні робити все можливе, щоб дотримуватися MVC. Вони - навколишнє середовище.
Джонатан Стерлінг

Насправді це можливо зробити, але для редагування imageNamed: (так, порушуючи безліч правил.) Потрібно вкрутити середовище виконання Objective-C: Якщо вам дійсно потрібно це зробити у своєму проекті з якихось важливих причин, див. Мою відповідь нижче.
Бен Готув,

3
@JonathanSterling існує багато різних інтерпретацій MVC
abbood

Це схоже на UIImage (з іменем: String) у Swift
RedEagle2000,

109

ви можете використовувати метод setAccessibilityIdentifier для будь-якого підкласу UIView

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

NSString *file_name = [image accessibilityIdentifier] ;

1
я натрапив тут просто б / к, я створюю додаток, який має локалізовані зображення .. і я хочу створити localizeметод, який просто проходить через зображення та робить певний регулярний вираз на імені зображення (у мене є дуже вагомі причини, щоб зробити такі зображення, а не створення спеціально створеного UIImage) .. мені було цікаво, чи є кращий чистіший спосіб локалізації зображень у
object

1
Я знаю, що з MVC не все в порядку, але мені це було потрібно для тестування.
Радек Вільчак

Для використання OSXaccessibilityDescription
Anoop Vaidya

чи є технічний недолік цього рішення? це здається найпростішим, найчистішим рішенням, тож чому це не вважається прийнятою відповіддю?
Крашалот

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: вам потрібно змінити розмір, коли ви хочете додати щось до існуючої поведінки. якщо ви будете використовувати категорію (або спадщину), ви зможете переключити якийсь код в інший, але ви не зможете цього зробити, не втрачаючи початкової поведінки. іншими словами, якщо ви спробуєте написати (у успадкованому класі): +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, як запропонував Нізар Ахмед?
Крашалот

10

Для цього немає рідного способу; однак ви можете легко створити таку поведінку самостійно.

Ви можете підклас UIImageViewі додати нову змінну екземпляра:

NSString* imageFileName;

Потім ви можете замінити setImage, спочатку встановивши imageFileNameім'я файлу зображення, яке ви встановлюєте, а потім зателефонувавши [super setImage:imageFileName]. Щось на зразок цього:

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

Те, що цього не можна зробити власним чином, не означає, що це неможливо :)


Дякуємо, що перенесли це і допомогли підтримувати сайт чистим!
jscs

10
if ([imageForCheckMark.image isEqual:[UIImage imageNamed:@"crossCheckMark.png"]]||[imageForCheckMark.image isEqual:[UIImage imageNamed:@"checkMark.png"]])
{

}

У стані if я просто перевіряю назву зображень
iEinstein

2
Відповіді лише на код не такі корисні. Будь ласка, додайте короткий текст, що пояснює, що робить ваш фрагмент коду.
неперевершено

якщо умова відповідає імені зображення в imageForCheckMark та [UIImage imageNamed: @ "crossCheckMark.png"]], якщо істина, то виконайте якийсь рядок коду, інакше інший рядок коду
iEinstein

Це все одно, що сказати нам, чи є зображення hot dogчи not hotdog.
ScottyBlades

Я створюю деякі unittests, щоб перевірити, чи встановлені правильні зображення, для мене це корисно.
MQoder,

9

Ні. Жодного способу не зробити це споконвічно. Вам доведеться підклас UIImageView та додати властивість imageFileName (яке ви встановлюєте при встановленні зображення).


привіт Кенні, будь-яка причина не просто використовувати setAccessibilityIdentifier, як запропонував Нізар Ахмед?
Крашалот

7

Ні UIImageView, ні UIImage не тримаються на назві файлу завантаженого зображення.

Ви можете будь-який

1: (як запропоновано Кенні Вінкером вище) підклас UIImageView, щоб мати властивість fileName або

2: назвіть файли зображень цифрами (image1.jpg, image2.jpg тощо) і позначте ці зображення відповідним номером (тег = 1 для image1.jpg, тег = 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
Джамал Зафар

Повертає Нуль, не намагайся цього
Кінгслі Мітчелл

в будь-якому випадку повертає нуль
Саранджіт

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"

Сподіваюся, це вам допоможе, удачі!


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()
}

1

Стрімкий 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

// потім у методі UIViewControllerin DidLoadto:

// 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)
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.