草庐IT

iOS 组件化加载 图片、gif、xib等文件(OC/Swift)

孤雁_南飞 2023-03-28 原文

前言

xcode 15.3
ios 10.0

起因,因为公司要使用保利威视的视频使用,我拿来他们的Module来封装做成组件来用,但是他们的xib文件一直是nil,为此困扰了我好久

说明

在组件化中,你的.assets中的图片,文件夹中的图片、gif图片,xib文件,json文件等都需要进行处理,否则找不到文件,加载不了,都会为nil,

1、在podspec设置生成bundle文件

在你的组件化文件pod -> .podspec文件中设置
PolyvOpenSourceModule/Assets.xcassets: 设置加载Assets.xcassets中的图片
PolyvOpenSourceModule//.xib:设置加载xib文件
PolyvOpenSourceModule/Images/
: 设置加载Module -> Images文件夹中的图片、gif图片、json文件等

  s.resource_bundles = {
    'Polyv_bundles' => ['PolyvOpenSourceModule/Assets.xcassets', 'PolyvOpenSourceModule/**/*.xib', 'PolyvOpenSourceModule/Images/*']
  }

2、在组件中加载文件

2.1、Objective-C

2.1.1 首先生成 NSBundle文件

FADeviceAssets.h 封装

+ (NSBundle *)hj_ResourceBundle;

FADeviceAssets.m 注意,此处的bundle文件名要和 .podspec 文件中设置的一致

static NSBundle *resourceBundle = nil;
static dispatch_once_t onceToken;

+ (NSBundle *)hj_ResourceBundle {
   dispatch_once(&onceToken, ^{
       NSString *resourceBundlePath = [[NSBundle bundleForClass:[self class]] pathForResource:@"Polyv_bundles" ofType:@"bundle"];
       resourceBundle = [NSBundle bundleWithPath:resourceBundlePath];
   });
   return resourceBundle;
}

2.1.2 加载图片

封装加载方法

@interface UIImage (Category)
+ (instancetype)hj_imageDevice:(NSString *)name;
@end


@implementation UIImage (Category) 
+ (instancetype)hj_imageDevice:(NSString *)name {
   return [UIImage imageNamed:name inBundle:[FADeviceAssets hj_ResourceBundle] compatibleWithTraitCollection:nil];
} 
@end

图片加载

UIImageView * imageView = [[UIImageView alloc] init];
imageView.image = [UIImage hj_imageDevice:@"FADevice_second_bg"]; 

2.1.3 gif 图片加载

此处我使用的是 FLAnimatedImage 加载本地gif

@interface FLAnimatedImage (Category)
+ (instancetype)hj_gif:(NSString *)name;
@end

@implementation FLAnimatedImage (Category) 
+ (instancetype)hj_gif:(NSString *)name {
    NSBundle * subBundle = [FADeviceAssets hj_ResourceBundle];
     
    NSURL * url = [subBundle URLForResource:name withExtension:@"gif"];
    NSData * imageData = [NSData dataWithContentsOfURL:url];
    return [FLAnimatedImage animatedImageWithGIFData:imageData];
} 
@end

加载方法

 FLAnimatedImageView * imageView = [[FLAnimatedImageView alloc] init];
 imageView.image = [UIImage hj_imageDevice:@"FADevice_second_auto"];

2.1.4 解析json

NSURL * url = [[FADeviceAssets hj_ResourceBundle] URLForResource:name withExtension:@"json"];
NSData * imageData = [NSData dataWithContentsOfURL:url];
NSDictionary * json = [NSJSONSerialization JSONObjectWithData:imageData options:NSJSONReadingMutableContainers error:nil];

2.1.5 加载 xib

此处也是我遇到的问题所在,头都给快给我整秃了

此处是原来加载的xib代码,无法加载

PLVVodPlayerSkin *skin = [[PLVVodPlayerSkin alloc] initWithNibName:nil bundle:nil];

更改后的

PLVVodPlayerSkin *skin = [[PLVVodPlayerSkin alloc] initWithNibName:@"PLVVodPlayerSkin" bundle:[FADeviceAssets hj_ResourceBundle]];

2.2 Swift

2.2.1 swift 加载图片

注意,此处的bundle文件名要和 .podspec 文件中设置的一致, 上面有说明,此处就不再次说明

extension UIImage {
    class func yl_image(named name: String) -> UIImage{
        return YLStudyAssets.bundledImage(named: name)
    }
}

open class YLStudyAssets: NSObject {
    internal class func bundledImage(named name: String) -> UIImage {
        let primaryBundle = Bundle(for: YLStudyAssets.self)
        if let image = UIImage(named: name, in: primaryBundle, compatibleWith: nil) {
            return image
        } else if
            let subBundleUrl = primaryBundle.url(forResource: "Polyv_bundles", withExtension: "bundle"),
            let subBundle = Bundle(url: subBundleUrl),
            let image = UIImage(named: name, in: subBundle, compatibleWith: nil){
            return image
        }
        return UIImage()
    }

}

图片加载

let imageView = UIImageView()
imageView.image = UIImage.yl_image(named: "")

2.2.2 加载gif图片

此处使用FLAnimatedImage加载,注意,此处的bundle文件名要和 .podspec 文件中设置的一致

import FLAnimatedImage
extension FLAnimatedImage {
    class func yl_gif(named name: String) -> FLAnimatedImage {
        return YLStudyAssets.bundleGif(named: name)
    }
}

open class YLStudyAssets: NSObject {
    internal class func bundleGif(named name: String) -> FLAnimatedImage {
        let primaryBundle = Bundle(for: YLStudyAssets.self)
        
        if let subBundleUrl = primaryBundle.url(forResource: "YLStudy_bundles", withExtension: "bundle"),
           let subBundle = Bundle(url: subBundleUrl),
           let url = subBundle.url(forResource: name, withExtension: "gif"),
           let imageData = try? Data(contentsOf: url) { 
                return FLAnimatedImage(animatedGIFData: imageData)
        }
        return FLAnimatedImage()
    }
}

gif图片加载

    private lazy var imageIcon: FLAnimatedImageView = {
        let imageView = FLAnimatedImageView() 
        imageView.animatedImage = FLAnimatedImage.yl_gif(named: "voiceLeft")
        
        return imageView
    }()

2.2.3 加载json

我此处是使用lottie-ios 加载动图,如果你要加载json文件,自己拆开做吧,按照oc处理,应该不难的

let primaryBundle = Bundle(for: YLHomeAssets.self)
let subBundleUrl = primaryBundle.url(forResource: "YLHome_bundles", withExtension: "bundle")
let subBundle = Bundle(url: subBundleUrl!) ?? Bundle.main 
let animation = Animation.named(fileName, bundle: subBundle)

其余有空补充

有关iOS 组件化加载 图片、gif、xib等文件(OC/Swift)的更多相关文章

  1. ruby - 如何在续集中重新加载表模式? - 2

    鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende

  2. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  3. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  4. ruby-on-rails - Ruby on Rails - 为文本区域和图片生成列 - 2

    我是Rails的新手,所以请原谅简单的问题。我正在为一家公司创建一个网站。那家公司想在网站上展示它的客户。我想让客户自己管理这个。我正在为“客户”生成一个表格,我想要的三列是:公司名称、公司描述和Logo。对于名称,我使用的是name:string但不确定如何在脚本/生成脚手架终端命令中最好地创建描述列(因为我打算将其设置为文本区域)和图片。我怀疑描述(我想成为一个文本区域)应该仍然是描述:字符串,然后以实际形式进行调整。不确定如何处理图片字段。那么……说来话长:我在脚手架命令中输入什么来生成描述和图片列? 最佳答案 对于“文本”数

  5. Ruby 文件 IO 定界符? - 2

    我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的

  6. ruby-on-rails - 使用 config.threadsafe 时从 lib/加载模块/类的正确方法是什么!选项? - 2

    我一直致力于让我们的Rails2.3.8应用程序在JRuby下正确运行。一切正常,直到我启用config.threadsafe!以实现JRuby提供的并发性。这导致lib/中的模块和类不再自动加载。使用config.threadsafe!启用:$rubyscript/runner-eproduction'pSim::Sim200Provisioner'/Users/amchale/.rvm/gems/jruby-1.5.1@web-services/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:105:in`co

  7. ruby-on-rails - 从应用程序中自定义文件夹内的命名空间自动加载 - 2

    我们目前正在为ROR3.2开发自定义cms引擎。在这个过程中,我们希望成为我们的rails应用程序中的一等公民的几个类类型起源,这意味着它们应该驻留在应用程序的app文件夹下,它是插件。目前我们有以下类型:数据源数据类型查看我在app文件夹下创建了多个目录来保存这些:应用/数据源应用/数据类型应用/View更多类型将随之而来,我有点担心应用程序文件夹被这么多目录污染。因此,我想将它们移动到一个子目录/模块中,该子目录/模块包含cms定义的所有类型。所有类都应位于MyCms命名空间内,目录布局应如下所示:应用程序/my_cms/data_source应用程序/my_cms/data_ty

  8. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  9. ruby - 为什么不能使用类IO的实例方法noecho? - 2

    print"Enteryourpassword:"pass=STDIN.noecho(&:gets)puts"Yourpasswordis#{pass}!"输出:Enteryourpassword:input.rb:2:in`':undefinedmethod`noecho'for#>(NoMethodError) 最佳答案 一开始require'io/console'后来的Ruby1.9.3 关于ruby-为什么不能使用类IO的实例方法noecho?,我们在StackOverflow上

  10. ruby-on-rails - 使用 gmaps4rails 动态加载谷歌地图标记 - 2

    如何只加载map边界内的标记gmaps4rails?当然,在平移和/或缩放后加载新的。与此直接相关的是,如何获取map的当前边界和缩放级别? 最佳答案 我是这样做的,我只在用户完成平移或缩放后替换标记,如果您需要不同的行为,请使用不同的事件监听器:在你看来(index.html.erb):{"zoom"=>15,"auto_adjust"=>false,"detect_location"=>true,"center_on_user"=>true}},false,true)%>在View的底部添加:functiongmaps4rail

随机推荐