UIImageView - Jak uzyskać nazwę pliku obrazu?

82

Czy można odczytać nazwę, UIImageView's UIImage która jest obecnie przechowywana w UIImageView?

Miałem nadzieję, że możesz zrobić coś takiego, ale nie rozgryzłem tego.

NSString *currentImageName = [MyIImageView getFileName];
Kuberchaun
źródło

Odpowiedzi:

88

Nie. Nie możesz tego zrobić.

Powodem jest to, że UIImageViewinstancja nie przechowuje pliku obrazu. Przechowuje wyświetla UIImageinstancję. Kiedy tworzysz obraz z pliku, robisz coś takiego:

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

Po wykonaniu tej czynności nie ma już odniesienia do nazwy pliku. UIImageInstancja zawiera dane, bez względu na to, gdzie dostał. Dlatego UIImageViewprawdopodobnie nie mogli znać nazwy pliku.

Ponadto, nawet gdybyś mógł, nigdy nie uzyskałbyś informacji o nazwie pliku z widoku. To łamie MVC.

Jonathan Sterling
źródło
62
To, że łamie MVC, nie oznacza, że ​​nie powinieneś tego robić. W końcu zasady mają być łamane;)
Sneakyness
10
Są pewne zasady. Ale na iPhonie i Macu zawsze powinieneś starać się przestrzegać MVC. To uparte środowiska.
Jonathan Sterling
W rzeczywistości jest to możliwe, ale wymaga wkręcenia się w środowisko uruchomieniowe Objective-C, aby edytować imageNamed: (tak, łamiąc wiele zasad). Jeśli naprawdę musisz to zrobić w swoim projekcie z jakiegoś ważnego powodu, zobacz moją odpowiedź poniżej.
Ben Gotow,
3
@JonathanSterling istnieje wiele różnych interpretacji MVC
opactwo
Wygląda jak UIImage (o nazwie: String) w Swift
RedEagle2000
109

możesz użyć metody setAccessibilityIdentifier dla dowolnej podklasy UIView

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

NSString *file_name = [image accessibilityIdentifier] ;
Nizar Ahmed
źródło
1
natknąłem się tutaj po prostu b / c Tworzę aplikację, która ma zlokalizowane obrazy ... i chcę utworzyć localizemetodę, która po prostu przejdzie przez obrazy i zrobi kilka wyrażeń regularnych na nazwie obrazu (mam bardzo dobre powody, aby te obrazy rzeczywistych obrazów zamiast tworzenia niestandardowego UIImage) .. zastanawiałem się, czy istnieje lepszy i czystszy sposób lokalizacji obrazów w obiektywnym-c .. skoro wszyscy mówią o MVC, a co nie
abbood
1
Wiem, że MVC nie jest w porządku, ale potrzebowałem go do testów.
Radek Wilczak
Do użytku w systemie OSXaccessibilityDescription
Anoop Vaidya,
czy jest jakaś techniczna wada tego rozwiązania? wydaje się, że to najprostsze, najczystsze rozwiązanie, więc dlaczego nie jest uważane za zaakceptowaną odpowiedź?
Crashalot
19

Nie, nie, nie… generalnie te rzeczy są możliwe. Po prostu poczujesz się jak brudna osoba. Jeśli absolutnie musisz, zrób to:

  • Utwórz kategorię z własną implementacją +imageNamed:(NSString*)imageNametych wywołań do istniejącej implementacji i użyj techniki określonej w tym miejscu ( Jak używać obiektu objc_setAssociatedObject / objc_getAssociatedObject w obiekcie? ), Aby trwale powiązać imageNamez zwracanym obiektem UIImage.

  • Użyj metody Swizzling, aby zamienić dostarczoną implementację imageNamed:dla swojej implementacji w tabeli wyszukiwania metod środowiska uruchomieniowego Objective-C.

  • Uzyskaj dostęp do nazwy skojarzonej z instancją UIImage (za pomocą objc_getAssociatedObject) w dowolnym momencie.

Mogę sprawdzić, czy to działa, z zastrzeżeniem, że nie można załadować nazw UIImage do NIB. Wygląda na to, że obrazy ładowane z NIB-ów nie są tworzone przez żadne standardowe wywołania funkcji, więc jest to dla mnie naprawdę tajemnicą.

Wdrożenie pozostawiam Tobie. Kopiowanie i wklejanie kodu, który wkręca się w środowisko uruchomieniowe Objective-C, jest bardzo złym pomysłem, więc zastanów się dokładnie nad potrzebami projektu i wdrażaj to tylko wtedy, gdy musisz.

Ben Gotow
źródło
1
Dlaczego po prostu nie utworzysz podklasy klasy, UIImageaby zastąpić metodę?
vrwim
vrwim: musisz wirować, gdy chcesz dodać coś do istniejącego zachowania. jeśli użyjesz kategorii (lub dziedziczenia), będziesz mógł zamienić jakiś kod na inny, ale nie będziesz w stanie tego zrobić bez utraty oryginalnego zachowania. innymi słowy, jeśli spróbujesz napisać (w klasie odziedziczonej): +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
cześć, ben jest jakiś powód, by nie używać tylko setAccessibilityIdentifier zgodnie z sugestią Nizara Ahmeda?
Crashalot
10

Nie ma na to rodzimego sposobu; jednak możesz łatwo stworzyć to zachowanie samodzielnie.

Możesz podklasować UIImageViewi dodać nową zmienną instancji:

NSString* imageFileName;

Następnie możesz nadpisać setImage, najpierw ustawiając imageFileNamenazwę pliku obrazu, który ustawiasz, a następnie dzwoniąc [super setImage:imageFileName]. Coś takiego:

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

To, że nie można tego zrobić natywnie, nie oznacza, że ​​jest to niemożliwe :)

WendiKidd
źródło
Dziękujemy za przeniesienie tego i pomoc w utrzymaniu witryny w czystości!
jscs
10
if ([imageForCheckMark.image isEqual:[UIImage imageNamed:@"crossCheckMark.png"]]||[imageForCheckMark.image isEqual:[UIImage imageNamed:@"checkMark.png"]])
{

}
iEinstein
źródło
W stanie sprawdzam tylko nazwy zdjęć
iEinstein,
2
Odpowiedzi zawierające tylko kod nie są tak przydatne. Dodaj krótki tekst wyjaśniający, co robi Twój fragment kodu.
nalply
jeśli warunek jest zgodny z nazwą obrazu w imageForCheckMark i [UIImage imageNamed: @ "crossCheckMark.png"]] jeśli jest spełniony, wykonaj jakąś linię kodu, w przeciwnym razie inną linię kodu
iEinstein
To tak, jakby powiedzieć nam, czy obraz jest, hot dogczy not hotdog.
ScottyBlades
Tworzę kilka wpisów, aby sprawdzić, czy ustawione są odpowiednie obrazy, dla mnie jest to przydatne.
MQoder
9

Nie. Nie można tego zrobić natywnie. Będziesz musiał podklasę UIImageView i dodać właściwość imageFileName (którą ustawisz podczas ustawiania obrazu).

Kenny Winker
źródło
cześć kenny, czy jest jakiś powód, by nie używać tylko setAccessibilityIdentifier zgodnie z sugestią nizara ahmeda?
Crashalot
7

Ani UIImageView, ani UIImage nie przechowuje nazwy załadowanego obrazu.

Możesz albo

1: (zgodnie z sugestią Kenny'ego Winkera powyżej) podklasa UIImageView, aby mieć właściwość fileName lub

2: nazwij pliki graficzne numerami (zdjęcie1.jpg, zdjęcie2.jpg itp.) I oznacz te obrazy odpowiednim numerem (tag = 1 dla obrazu1.jpg, tag = 2 dla obrazu2.jpg itp.) Lub

3: Miej zmienną na poziomie klasy (np. NSString * currentFileName), która jest aktualizowana za każdym razem, gdy aktualizujesz obraz UIImageView

Mihir Mathuria
źródło
3

Ten kod pomoże ci: -

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

Użyj tego jako: -

NSString *currentImageName = [self getFileName:MyIImageView];
junaidsidhu
źródło
Zwróci wartość null, ponieważ nie ustawiłeś jeszcze accessibilityIdentifier. Ustaw to w ten sposób, [image setAccessibilityIdentifier:@"demoFileName.png"] ;a następnie wywołaj tę metodę
NSNoob
Konsola mówi: błąd: nie znaleziono właściwości „accessibilityIdentifier” w obiekcie typu „UIImage *” - Xcode 8.1
Jamal Zafar
Zwraca Null, nie próbuj tego
Kingsley Mitchell
w każdym razie zwraca zero
Saranjith
3

Możesz też użyć identyfikatora przywrócenia, na przykład:

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"

Zasadniczo w tym rozwiązaniu używasz identyfikatora przywracania do przechowywania nazwy obrazu, dzięki czemu możesz go później użyć w dowolnym miejscu. Jeśli zaktualizujesz obraz, musisz również zaktualizować identyfikator przywracania, na przykład:

myImageView.restorationIdentifier = "newImageName"

Mam nadzieję, że ci to pomoże, powodzenia!

ThiagoAM
źródło
2

Tak, możesz porównać dane, takie jak poniższy kod

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;
}
Hardik Mamtora
źródło
2

Możesz użyć funkcji Objective c Runtime do skojarzenia nazwy obrazu z UImageView.

Pierwszy import #import <objc/runtime.h>w Twojej klasie

następnie zaimplementuj swój kod jak poniżej:

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");

Mam nadzieję, że ci to pomoże.

Nishant Tyagi
źródło
2

Pobierz nazwę obrazu Swift 4.2

Jest sposób, jeśli chcesz porównać nazwy obrazów przycisków, które masz w zasobach.

@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
źródło
1

Szybki 3

Najpierw ustaw accessibilityIdentifier jako imageName

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

Następnie użyj następującego kodu.

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

Wreszcie, wywołujący sposób metody identyfikacji

myImageView.getFileName()
Abdul Hameed
źródło
0

Zajmowałem się tym problemem, rozwiązałem go za pomocą wzorca projektowego MVC, stworzyłem klasę Card:

@interface Card : NSObject

@property (strong,nonatomic) UIImage* img;

@property  (strong,nonatomic) NSString* url;

@end

// następnie w UIViewControllerw DidLoadMetodzie zrobić:

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

// na przykład

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

// możesz sprawdzić nazwę obrazu, więc możesz to zrobić:

//na przykład

 NSString * str = @"image.jpg";

 if([str isEqualToString: [card10 url]]){
 // your code here
 }
Hasan Sawaed
źródło
-1

użyj poniżej

 UIImageView *imageView = ((UIImageView *)(barButtonItem.customView.subviews.lastObject));
 file_name = imageView.accessibilityLabel;
ramo
źródło
-1

Kod działa w swift3 - napisz kod wewnątrz metody delegata 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)
}
Niraj Paul
źródło