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];

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.


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] ;

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.


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 :)


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"]])
{

}

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).


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


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];

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!


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;
}

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.


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

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

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
 }

-1

użyj poniżej

 UIImageView *imageView = ((UIImageView *)(barButtonItem.customView.subviews.lastObject));
 file_name = imageView.accessibilityLabel;

-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)
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.