UIImageView - Làm thế nào để lấy tên tệp của hình ảnh được gán?


82

Có thể đọc tên của một UIImageView's UIImage hiện được lưu trữ trong UIImageViewkhông?

Tôi đã hy vọng bạn có thể làm điều gì đó như thế này, nhưng chưa tìm ra.

NSString *currentImageName = [MyIImageView getFileName];

Câu trả lời:


88

Không. Bạn không thể làm điều đó.

Lý do là một UIImageViewphiên bản không lưu trữ tệp hình ảnh. Nó lưu trữ một phiên bản hiển thị UIImage. Khi bạn tạo một hình ảnh từ một tệp, bạn làm như sau:

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

Khi điều này được thực hiện, không còn bất kỳ tham chiếu nào đến tên tệp. Cá UIImagethể chứa dữ liệu, bất kể nó lấy từ đâu. Do đó, UIImageViewkhông thể biết tên tệp.

Ngoài ra, ngay cả khi bạn có thể, bạn sẽ không bao giờ nhận được thông tin tên tệp từ một chế độ xem. Điều đó phá vỡ MVC.


62
Chỉ vì nó phá vỡ MVC không có nghĩa là bạn không nên làm điều đó. Nội quy có nghĩa là để bị phá vỡ, sau khi tất cả;)
Sneakyness

10
Một số quy tắc là. Nhưng trên iPhone và Mac, bạn phải luôn cố gắng hết sức để tuân thủ MVC. Họ là những môi trường cố chấp.
Jonathan Sterling

Thực sự có thể làm được điều này, nhưng nó đòi hỏi phải bắt kịp thời gian chạy Objective-C để chỉnh sửa imageNamed: (vâng, vi phạm nhiều quy tắc.) Nếu bạn thực sự phải làm điều này trong dự án của mình vì một số lý do quan trọng, hãy xem câu trả lời của tôi bên dưới.
Ben Gotow

3
@JonathanSterling có nhiều cách hiểu khác nhau về MVC
abbood

Có vẻ như UIImage (có tên: String) trong Swift
RedEagle2000,

109

bạn có thể sử dụng phương thức setAccessibilityIdentifier cho bất kỳ lớp con nào của UIView

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

NSString *file_name = [image accessibilityIdentifier] ;

1
Tôi đã xem qua đây chỉ đơn giản là tôi đang tạo một ứng dụng có các hình ảnh được bản địa hóa .. và tôi muốn tạo một localizephương pháp chỉ đơn giản là lướt qua các hình ảnh và thực hiện một số biểu tượng trên tên hình ảnh (tôi có lý do rất tốt để làm hình ảnh hình ảnh thực tế chứ không phải là tạo ra một tùy chỉnh thực hiện UIImage) .. tôi đã tự hỏi nếu có một trình dọn dẹp cách tốt hơn để bản địa hóa hình ảnh trong Objective-c .. kể từ khi tất cả mọi người đang nói về MVC và những gì không
abbood

1
Tôi biết không có gì tốt với MVC, nhưng tôi cần nó với mục đích thử nghiệm.
Radek Wilczak

Để sử dụng OSXaccessibilityDescription
Anoop Vaidya

là có một nhược điểm kỹ thuật cho giải pháp này? Đây có vẻ là giải pháp đơn giản nhất, sạch sẽ nhất, vậy tại sao nó không được coi là câu trả lời được chấp nhận?
Crashalot

19

Không không không… nói chung những điều này là có thể. Nó sẽ chỉ làm cho bạn cảm thấy như một người bẩn thỉu. Nếu bạn nhất thiết phải làm như sau:

  • Tạo một danh mục bằng cách triển khai của riêng bạn đối với việc triển khai +imageNamed:(NSString*)imageNameđó và sử dụng kỹ thuật được xác định ở đây ( Làm cách nào để sử dụng objc_setAssociatedObject / objc_getAssociatedObject bên trong một đối tượng? ) Để liên kết vĩnh viễn imageNamevới đối tượng UIImage được trả về.

  • Sử dụng Phương pháp Swizzling để hoán đổi phần triển khai được cung cấp cho việc triển khai của imageNamed:bạn trong bảng tra cứu phương pháp của thời gian chạy Objective-C.

  • Truy cập vào tên bạn đã liên kết với cá thể UIImage (sử dụng objc_getAssociatedObject) bất cứ lúc nào bạn muốn.

Tôi có thể xác minh rằng điều này hoạt động, với lưu ý rằng bạn không thể tải tên của UIImage trong NIB. Có vẻ như hình ảnh được tải từ NIB không được tạo ra thông qua bất kỳ lệnh gọi hàm tiêu chuẩn nào, vì vậy nó thực sự là một bí ẩn đối với tôi.

Tôi để việc triển khai cho bạn. Sao chép-dán mã bắt vít với thời gian chạy Objective-C là một ý tưởng rất tồi, vì vậy hãy suy nghĩ kỹ về nhu cầu dự án của bạn và chỉ thực hiện điều này nếu bạn phải.


1
Tại sao bạn không tạo một lớp con UIImageđể ghi đè một phương thức?
vrwim

vrwim: bạn cần phải xoay khi muốn thêm điều gì đó vào hành vi hiện có. nếu bạn sẽ sử dụng danh mục (hoặc kế thừa), bạn sẽ có thể chuyển một số mã sang một mã khác, nhưng bạn sẽ không thể làm điều đó mà không mất hành vi ban đầu. nói cách khác, nếu bạn sẽ cố gắng viết (trong lớp được thừa kế): +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

chào bạn, bất kỳ lý do nào để không chỉ sử dụng setAccessibilityIdentifier theo đề xuất của nizar ahmed?
Crashalot

10

Không có cách bản địa để làm điều này; tuy nhiên, bạn có thể dễ dàng tự tạo ra hành vi này.

Bạn có thể phân lớp UIImageViewvà thêm một biến phiên bản mới:

NSString* imageFileName;

Sau đó, bạn có thể ghi đè setImage, trước tiên đặt imageFileNamethành tên tệp của hình ảnh bạn đang đặt, sau đó gọi [super setImage:imageFileName]. Một cái gì đó như thế này:

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

Chỉ vì nó không thể được thực hiện một cách tự nhiên không có nghĩa là nó không thể :)


Cảm ơn bạn đã chuyển cái này và giúp giữ trang web sạch sẽ!
jscs

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

}

Trong điều kiện, tôi chỉ cần kiểm tra tên của hình ảnh
iEinstein

2
Câu trả lời chỉ có mã không quá hữu ích. Vui lòng thêm một đoạn văn bản ngắn giải thích chức năng của đoạn mã của bạn.
nalply

nếu điều kiện khớp với tên hình ảnh trong imageForCheckMark và [UIImage imageNamed: @ "crossCheckMark.png"]] nếu đúng thì hãy thực thi một số dòng mã nếu không thì dòng mã khác
iEinstein 19/02/13

Điều này giống như cho chúng tôi biết hình ảnh nếu hot doghoặc not hotdog.
ScottyBlades

Tôi đang tạo một số unittest để kiểm tra xem hình ảnh có được đặt phù hợp hay không, đối với tôi điều này rất hữu ích.
MQoder

9

Không. Không có cách nào để làm điều đó một cách tự nhiên. Bạn sẽ phải phân lớp UIImageView và thêm thuộc tính imageFileName (thuộc tính mà bạn đặt khi đặt hình ảnh).


chào kenny có lý do gì để không chỉ sử dụng setAccessibilityIdentifier theo đề xuất của nizar ahmed không?
Crashalot

7

Cả UIImageView không phải UIImage đều không giữ tên tệp của hình ảnh được tải.

Bạn có thể

1: (theo đề xuất của Kenny Winker ở trên) lớp con UIImageView để có thuộc tính fileName hoặc

2: đặt tên tệp hình ảnh bằng số (image1.jpg, image2.jpg, v.v.) và gắn thẻ những hình ảnh đó bằng số tương ứng (tag = 1 cho image1.jpg, tag = 2 cho image2.jpg, v.v.) hoặc

3: Có một biến cấp độ lớp (ví dụ: NSString * currentFileName) cập nhật bất cứ khi nào bạn cập nhật hình ảnh của UIImageView


3

Mã này sẽ giúp bạn: -

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

Sử dụng như sau: -

NSString *currentImageName = [self getFileName:MyIImageView];

Nó sẽ trả về null vì bạn chưa đặt accessibilityIdentifier. Thiết lập nó như thế này [image setAccessibilityIdentifier:@"demoFileName.png"] ;và sau đó gọi phương pháp này
NSNoob

Bảng điều khiển nói: lỗi: bất động sản 'accessibilityIdentifier' không tìm thấy trên đối tượng của loại 'UIImage *' - Xcode 8.1
Jamal Zafar

Trả Null, đừng cố này
Kingsley Mitchell

anyway nó trả về null
Saranjith

3

Hoặc bạn có thể sử dụng số nhận dạng khôi phục, như sau:

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"

Về cơ bản trong giải pháp này, bạn đang sử dụng mã nhận dạng khôi phục để giữ tên của hình ảnh, vì vậy bạn có thể sử dụng nó sau này ở bất cứ đâu. Nếu bạn cập nhật hình ảnh, bạn cũng phải cập nhật số nhận dạng khôi phục, như sau:

myImageView.restorationIdentifier = "newImageName"

Tôi hy vọng rằng sẽ giúp bạn, chúc may mắn!


2

Có, bạn có thể so sánh với sự trợ giúp của dữ liệu như mã dưới đây

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

Bạn có thể sử dụng tính năng Runtime c mục tiêu để liên kết tên hình ảnh với UImageView.

Lần nhập khẩu đầu tiên #import <objc/runtime.h> trong lớp của bạn

sau đó triển khai mã của bạn như sau:

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

Hy vọng nó sẽ giúp bạn.


2

Lấy tên hình ảnh Swift 4.2

Có một cách nếu bạn muốn so sánh tên hình ảnh nút mà bạn có trong nội dung.

@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

Swift 3

Đầu tiên hãy đặt AccessibilityIdentifier là imageName

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

Sau đó, sử dụng mã sau.

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

Cuối cùng, cách gọi của phương pháp để xác định

myImageView.getFileName()

0

Tôi đã giải quyết vấn đề này, tôi đã được giải quyết bằng mẫu thiết kế MVC, tôi đã tạo lớp Thẻ:

@interface Card : NSObject

@property (strong,nonatomic) UIImage* img;

@property  (strong,nonatomic) NSString* url;

@end

// sau đó trong UIViewControllertrong DidLoadphương pháp để làm:

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

// ví dụ

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

// có thể bạn muốn kiểm tra tên hình ảnh, vì vậy bạn có thể làm điều này:

//ví dụ

 NSString * str = @"image.jpg";

 if([str isEqualToString: [card10 url]]){
 // your code here
 }

-1

sử dụng bên dưới

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

-1

Mã hoạt động trong swift3 - viết mã bên trong phương thức ủy nhiệm 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)
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.