- iOS组件化(一) - 学习和整理
- iOS组件化(二) - iOS本地组件化管理
- iOS组件化(三) - iOS中使用CocoaPods进行私有组件远程管理
- iOS组件化(四) - iOS组件中图片文件资源的使用
以上文章详细介绍了各个情况的资源文件
本文仅限于使用模块的项目PodFile
中使用use_frameworks!
的情况
一、组件中代码和资源的位置
1. 项目中代码放在组件目录下的Classes
下
2. 项目中图片等资源放在组件目录下的Assets
下
3. .podspec
中的图片资源配置
其中InformationModuleImageBundle
为图片资源的bundle
名,后面为资源路径
# 设置图片资源
s.resource_bundles = {
'InformationModuleImageBundle' => ['InformationModule/Assets/*']
}
二、使用模块的项目PodFile
中使用use_frameworks!
的情况
使用组件的项目的PodFile
使用use_frameworks!
,则资源在APP中所在路径为:
/Build/Products/Debug-iphonesimulator/InformationModule_Example.app/Frameworks/InformationModule.framework/InformationModuleImageBundle.bundle
具体查看资源方法:
1. 右键.app
文件,show in finder
2. 显示包内容
3. Feameworks
- .framework
- .bundle
4. 图片
5. 图片在Pods
中的位置
三、定义获取组件中图片和文件资源的Util
//
// InformationModuleUtil.swift
// TestDemo
//
// Created by yuanzhiying on 2021/7/30.
//
import UIKit
open class InformationModuleUtil {
// 通用 - 获取InformationModule.framework的Bundle
static func getInformationModuleFrameworkBundle(_ moduleName: String = "InformationModule") -> Bundle? {
// 先进入MainBundle下的Frameworks文件夹下
if var bundleURL = Bundle.main.url(forResource: "Frameworks", withExtension: nil) {
// 再进入InformationModule.framework包下
bundleURL = bundleURL.appendingPathComponent(moduleName)
bundleURL = bundleURL.appendingPathExtension("framework")
// 拿到InformationModule.framework的Bundle
return Bundle(url: bundleURL)
}
return nil
}
// 获取组件中的图片
// 组件中的图片在InformationModule.framework下的InformationModuleImageBundle.bundle下
// 组件中图片在组件项目中的路径是在assets文件夹下
// 2. 图片没有放在imageset里,imageName直接使用imageName.png
// 3. 如果放在dou.imageset/里,则imageName传"dou.imageset/dou.png"
public static func getImformationModuleImage(imageName: String, _ resourceBundle: String = "InformationModuleImageBundle") -> UIImage? {
if let informationModuleFrameworkBundle = getInformationModuleFrameworkBundle() {
// 获取InformationModuleImageBundle.bundle路径
if let tempBundleURL = informationModuleFrameworkBundle.url(forResource: resourceBundle, withExtension: "bundle") {
// 获取InformationModuleImageBundle.bundle的Bundle
let tempBundle = Bundle(url: tempBundleURL)
// 拿InformationModuleImageBundle.bundle下的头文件
if let file = tempBundle?.path(forResource: imageName, ofType: nil) {
return UIImage(contentsOfFile: file)
}
}
}
return nil
}
// 获取组件中的storyboard
// 组件中的storyboard在InformationModule.framework下
public static func getInformationModuleStoryboard(storyboardName: String, _ moduleName: String = "InformationModule") -> UIStoryboard? {
if let informationModuleFrameworkBundle = getInformationModuleFrameworkBundle() {
return UIStoryboard(name: storyboardName, bundle: informationModuleFrameworkBundle)
}
return nil
}
}
四、在项目中使用组件的资源、类、文件
//
// ViewController.swift
// InformationModule
//
// Created by 873965092@qq.com on 07/28/2021.
// Copyright (c) 2021 873965092@qq.com. All rights reserved.
//
import InformationModule
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
/// 引用组件中的UIView
let testView = TestView(frame: CGRect(x: 50, y: 50, width: 120, height: 120))
testView.backgroundColor = UIColor.red
view.addSubview(testView)
// 引用组件中的类和方法
let model = InformationModel()
model.helloWorld()
// 获取并展示组件中的图片资源
let imageView = UIImageView(frame: CGRect(x: 200, y: 300, width: 20, height: 25))
imageView.image = InformationModuleUtil.getImformationModuleImage(imageName: "phone.png")
view.addSubview(imageView)
// 获取并展示组件中的图片资源
let imageView2 = UIImageView(frame: CGRect(x: 150, y: 350, width: 72, height: 29))
imageView2.image = InformationModuleUtil.getImformationModuleImage(imageName: "dou.imageset/dou.png")
view.addSubview(imageView2)
}
@IBAction func pushStoryboard(_ sender: Any) {
let storyboard = InformationModuleUtil.getInformationModuleStoryboard(storyboardName: "InformationPage")
if let vc = storyboard?.instantiateViewController(withIdentifier: "InformationPage") {
present(vc, animated: true, completion: nil)
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
五、在组件中使用组件中的资源、图片、文件、类等
InformationPage
//
// InformationPage.swift
// InformationModule
//
// Created by yuanzhiying on 2021/7/30.
//
import UIKit
class InformationPage: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.view.backgroundColor = UIColor.white
let pushStoryboardButton = UIButton(type: .custom)
pushStoryboardButton.frame = CGRect(x: 50, y: 250, width: 250, height: 250)
pushStoryboardButton.backgroundColor = UIColor.blue
pushStoryboardButton.setTitle("pushSecondStoryboard", for: .normal)
pushStoryboardButton.setTitleColor(UIColor.white, for: .normal)
pushStoryboardButton.addTarget(self, action: #selector(pushStoryboardPage), for: .touchUpInside)
self.view.addSubview(pushStoryboardButton)
}
@objc func pushStoryboardPage() {
let storyboard = InformationModuleUtil.getInformationModuleStoryboard(storyboardName: "SecondViewController")
if let vc = storyboard?.instantiateViewController(withIdentifier: "SecondViewController") {
self.present(vc, animated: true, completion: nil)
}
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
}
TestView
//
// TestView.swift
// InformationModule
//
// Created by yuanzhiying on 2021/7/30.
//
import UIKit
open class TestView: UIView {
override public init(frame: CGRect) {
super.init(frame: frame)
// 组件中展示组件中的图片资源
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 20, height: 25))
imageView.image = InformationModuleUtil.getImformationModuleImage(imageName: "phone.png")
addSubview(imageView)
}
public required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
InformationPage.storyboard
使用InformationModuleImageBundle.bundle/dou.imageset/dou.png
使用InformationModuleImageBundle.bundle/phone.png