UIImageView - 如何获取分配的图像的文件名?

Posted

技术标签:

【中文标题】UIImageView - 如何获取分配的图像的文件名?【英文标题】:UIImageView - How to get the file name of the image assigned? 【发布时间】:2009-11-16 05:36:10 【问题描述】:

是否可以读取UIImageView's UIImage 的名称 目前存储在UIImageView?

我希望你能做这样的事情,但还没有想通。

NSString *currentImageName = [MyIImageView getFileName];

【问题讨论】:

访问***.com/questions/47246387/… 【参考方案1】:

您可以对 UIView 的任何子类使用 setAccessibilityIdentifier 方法

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

NSString *file_name = [image accessibilityIdentifier] ;

【讨论】:

我在这里遇到的只是 b/c 我正在创建一个具有本地化图像的应用程序.. 我想创建一个 localize 方法,它只是遍历图像并在图像名称(我有很好的理由让这些图像成为实际图像,而不是创建定制的 UIImage).. 我想知道是否有更好更简洁的方法在 Objective-c 中本地化图像.. 因为每个人都在谈论 MVC 和什么不是 我知道 MVC 不行,但我在测试时需要它。 对于 OSX 使用 accessibilityDescription 此解决方案是否存在技术缺陷?这似乎是最简单、最干净的解决方案,为什么它不被认为是公认的答案?【参考方案2】:

不。你不能那样做。

原因是UIImageView 实例不存储图像文件。它存储一个显示一个UIImage 实例。当您从文件制作图像时,您会执行以下操作:

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

完成此操作后,将不再有对文件名的任何引用。 UIImage 实例包含数据,无论它从何处获取。因此,UIImageView 不可能知道文件名。

此外,即使可以,您也永远无法从视图中获取文件名信息。这破坏了 MVC。

【讨论】:

仅仅因为它破坏了 MVC 并不意味着你不应该这样做。毕竟,规则是用来打破的;) 有些规则是。但在 iPhone 和 Mac 上,您应该始终尽最大努力遵守 MVC。它们是固执己见的环境。 实际上可以做到这一点,但它需要使用 Objective-C 运行时来编辑 imageNamed:(是的,违反 很多 条规则。)如果你真的必须出于某些重要原因在您的项目中执行此操作,请参阅下面的答案。 @JonathanSterling MVC 有很多不同的解释 它看起来像 Swift 中的 UIImage(named: String)【参考方案3】:

不不不……总的来说,这些事情都是可能的。它只会让你觉得自己像个肮脏的人。如果您绝对必须这样做,请执行以下操作:

使用您自己的+imageNamed:(NSString*)imageName 实现创建一个类别,该类别调用现有实现并使用此处确定的技术 (How do I use objc_setAssociatedObject/objc_getAssociatedObject inside an object?) 将imageName 与返回的 UIImage 对象永久关联。

使用Method Swizzling 将提供的imageNamed: 实现交换为您在Objective-C 运行时的方法查找表中的实现。

随时访问您与 UIImage 实例关联的名称(使用 objc_getAssociatedObject)。

我可以验证这是否有效,但需要注意的是,您无法获取在 NIB 中加载的 UIImage 的名称。似乎从 NIB 加载的图像不是通过任何标准函数调用创建的,所以这对我来说真的是个谜。

我将把实现留给你。复制粘贴与 Objective-C 运行时相关的代码是一个非常糟糕的主意,因此请仔细考虑项目的需求并仅在必要时实施。

【讨论】:

为什么不直接创建UIImage 的子类来覆盖一个方法? 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 您好,您有什么理由不按照 nizar ahmed 的建议使用 setAccessibilityIdentifier?【参考方案4】:

没有本地方法可以做到这一点;但是,您可以自己轻松地创建此行为。

你可以继承UIImageView并添加一个新的实例变量:

NSString* imageFileName;

然后您可以覆盖setImage,首先将imageFileName 设置为您正在设置的图像的文件名,然后调用[super setImage:imageFileName]。像这样的:

-(void) setImage:(NSString*)fileName

   imageFileName = fileName;
   [super setImage:fileName];

仅仅因为它不能在本地完成并不意味着它不可能:)

【讨论】:

感谢您搬家并帮助保持网站清洁!【参考方案5】:
if ([imageForCheckMark.image isEqual:[UIImage imageNamed:@"crossCheckMark.png"]]||[imageForCheckMark.image isEqual:[UIImage imageNamed:@"checkMark.png"]])



【讨论】:

如果条件我刚刚检查了图像的名称 纯代码答案没那么有用。请添加一段简短的文字来解释您的代码片段的作用。 如果条件与 imageForCheckMark 和 [UIImage imageNamed:@"crossCheckMark.png"]] 中的图像名称匹配,如果为真则执行某行代码,否则执行不同的代码行 这就像告诉我们图像是hot dog还是not hotdog 我正在创建一些单元测试来检查是否设置了正确的图像,这对我来说很有用。【参考方案6】:

不。没有办法在本地做到这一点。 您将不得不继承 UIImageView,并添加一个 imageFileName 属性(您在设置图像时设置)。

【讨论】:

嗨 kenny 有什么理由不按照 nizar ahmed 的建议使用 setAccessibilityIdentifier 吗?【参考方案7】:

UIImageView 和 UIImage 都不保留加载图像的文件名。

你可以

1:(正如上面 Kenny Winker 所建议的)子类 UIImageView 以具有 fileName 属性或

2:用数字命名图像文件(image1.jpg,image2.jpg等)并用相应的数字标记这些图像(tag=1 for image1.jpg,tag=2 for image2.jpg etc)或

3:有一个类级别的变量(例如 NSString *currentFileName),它会在您更新 UIImageView 的图像时更新

【讨论】:

【参考方案8】:

或者您可以使用恢复标识符,如下所示:

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"

希望对你有帮助,祝你好运!

【讨论】:

【参考方案9】:

此代码将帮助您:-

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

将此用作:-

NSString *currentImageName = [self getFileName:MyIImageView];

【讨论】:

它会返回 null 因为你还没有设置accessibilityIdentifier。像这样设置[image setAccessibilityIdentifier:@"demoFileName.png"] ;然后调用这个方法 控制台说:错误:在'UIImage *'类型的对象上找不到属性'accessibilityIdentifier' - Xcode 8.1 返回 Null,不要尝试这个 无论如何它都会返回 null【参考方案10】:

是的,您可以借助以下代码的数据进行比较

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;

【讨论】:

【参考方案11】:

您可以使用 Objective c Runtime 功能将图像名称与 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");

希望对你有所帮助。

【讨论】:

【参考方案12】:

获取图片名称 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()

【讨论】:

【参考方案13】:

斯威夫特 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()

【讨论】:

【参考方案14】:

我已经处理过这个问题,我已经通过 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
 

【讨论】:

【参考方案15】:

在下面使用

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

【讨论】:

【参考方案16】:

代码在 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)

【讨论】:

以上是关于UIImageView - 如何获取分配的图像的文件名?的主要内容,如果未能解决你的问题,请参考以下文章

如何将图片分配给 UIImageView (Swift 3)

为 UIImageView 分配图像问题

如何使用 Swift 模糊 UIImageView 中的现有图像?

将图像分配给 UIImageView

如何以全分辨率从 UIImageView 获取旋转、缩放和平移的图像?

如何快速从文件夹中获取随机图像?