如何访问iOS私有库中的图片、Xib资源

我们制作私有库时,若要在私有库中使用图片,需要在podSpec文件中指定图片来源。

s.resource_bundles = {
    'KDIBaseUI' => ['KDIBaseUI/Assets/*']
}

这样,图片会放在一个资源bundle中。

对于私有库工程来说,直接通过[UIImage imageNamed:@"xxx"]的形式访问即可。比较麻烦的是,从其他工程访问私有库图片的情况。

从其他工程访问私有库图片

其他工程使用私有库时,私有库的资源bundlemainBundle的目录下。我们想要访问图片,第一步是找到这个资源bundle,然后才能找到图片。

+ (UIImage *)imageNamed:(NSString *)imageName bundleNamed:(NSString *)bundleNamed {
    UIImage *image = nil;
    //根据bundleNamed寻找指定bundle
    NSURL *bundleURL = [[NSBundle mainBundle] URLForResource:bundleNamed withExtension:@"bundle"];
    if (bundleURL) {
        NSBundle *bundle = [NSBundle bundleWithURL:bundleURL];
        NSInteger scale = [[UIScreen mainScreen] scale];
        NSString *scaleName = [NSString stringWithFormat:@"%@@%zdx.png", imageName, scale];
        
        //加载图片
        image = [UIImage imageWithContentsOfFile:[bundle pathForResource:scaleName ofType:nil]];
        
        //如果没有对应scale的图,则尝试使用2x图
        if (image == nil) {
            scaleName = [NSString stringWithFormat:@"%@@2x.png", imageName];
        }
        
        image = [UIImage imageWithContentsOfFile:[bundle pathForResource:scaleName ofType:nil]];
    }
    return image;
}

从其他工程使用私有库Xib文件

Xib文件其实也是一种资源,所以需要将Xib文件放到图片资源所在的文件夹内。

我们平时注册tableViewCell的Xib时,一般是这样的操作:

[self.tableView registerNib:[UINib nibWithNibName:@"KDOHNormalTableViewCell" bundle:nil] forCellReuseIdentifier:@"KDOHNormalTableViewCell"];

如果这个Xib是来自于私有库的,那么在加载这个cell时,肯定会报找不到资源的错误:

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Could not load NIB in bundle: 'KDOHLanguageBundle  (loaded)' with name 'KDOHNormalTableViewCell''

原因在于:默认情况下,是从mainBundle中寻找这个Xib的,但实际上这个Xib位于私有库的资源bundle中。所以我们注册cell时,需要指定查找的bundle.

NSBundle *bundle = [NSBundle subBundleWithBundleName:@"KDIBaseUI" targetClass:[self class]];
[self.tableView registerNib:[UINib nibWithNibName:@"KDOHNormalTableViewCell" bundle:bundle] forCellReuseIdentifier:@"KDOHNormalTableViewCell"];
    

查找bundle细节代码如下:

/// 从指定类所在的bundle里,获取某个子bundle
/// @param bundleName 子bundle名字
/// @param targetClass 指定类
+ (instancetype)subBundleWithBundleName:(NSString *)bundleName targetClass:(Class)targetClass {
    
    NSBundle *bundle = [NSBundle bundleForClass:targetClass];
    NSString *path = [bundle pathForResource:bundleName ofType:@"bundle"];
    
    return path?[NSBundle bundleWithPath:path]:[NSBundle mainBundle];
}

总结

访问私有库中的资源,需要指定该资源所在的bundle。

你可能感兴趣的:(如何访问iOS私有库中的图片、Xib资源)