本篇是iOS项目实践的最后一篇。大家可以下载demo,根据这几篇文章流程实现一个现有项目的组件化。当然,每个公司根据自己的业务需求组件化的方式会有所不同,但大概的思路和流程不会有很大的差异。
上一篇中完成了专题组件和作者组件的集成及管理。但是加载XIB和图片时任然存在一些问题。切回到FFSpecialKit组件,当点击专题界面中的cell时会报错。这是因为项目中用到XIB加载出错了。
拷贝路径到Finder前往去查看一下,如下图所示指定的bundle路径下确实没有FFSpecialDetailView这样的XIB文件。
回到代码查看一下,原来加载XIB的方式如下:
显然通过加载上面的bundle的方式加载不到XIB,需要重新设置budle的路径,修改如下:
拷贝路径前往查看,XIB果然在指定的bundle下
再次运行,点击专题cell测试就可以正常跳转了。不难发现cell中一些图片资源未显示(比如:灰色的线、评论、点赞等图标),接下来需要处理这些图片资源显示的问题。
是否记得在FFSpecialKit中和Classes文件夹同级有个Assets文件夹,该文件夹专门用来存放组件的资源文件。
接着,把图片资源拖入Assets文件夹,需要修改.podspec文件,打开资源的加载路径,然后执行pod install。然后会发现多了一个Resource的资源文件夹。
运行发现图片任然未显示,这是因为项目中是通过[UIImage imageNamed:@“图片名"]
方式加载本地图片,这种方式默认是从mainBundle中去加载图片,和XIB的问题一样也会找不到图片。
我们发现图片实际是在FFSpecialKit组件下FFSpecialKit.bundle
里面,因此需要改变图片的加载方式.
说明:必须指明图片的全名和图片所在bundle的包名.
因为涉及到@2x,@3x图片这里不能写成固定的,应该按照scale来设置
再次运行图片就显示了
因为之前设置图片的方式都需要修改,上面修改图片加载方式的代码在很多地方都会用到,所以最好的做法就是抽取一个工具方法,笔者这里是添加了一个UIImage的分类。把这个分类添加到基础组件FFCategory中,更新组件就ok了。
#import
@interface UIImage (Extension)
+ (instancetype)ff_imagePathWithName:(NSString *)imageName bundle:(NSString *)bundle targetClass:(Class)targetClass;
@end
#import "UIImage+Extension.h"
@implementation UIImage (Extension)
+ (instancetype)ff_imagePathWithName:(NSString *)imageName bundle:(NSString *)bundle targetClass:(Class)targetClass {
NSInteger scale = [[UIScreen mainScreen] scale];
NSBundle *currentBundle = [NSBundle bundleForClass:targetClass];
NSString *name = [NSString stringWithFormat:@"%@@%zdx",imageName,scale];
NSString *dir = [NSString stringWithFormat:@"%@.bundle",bundle];
NSString *path = [currentBundle pathForResource:name ofType:@"png" inDirectory:dir];
return path ? [UIImage imageWithContentsOfFile:path] : nil;
}
@end
回到项目用该Category更新代码
再次运行,相关图片就显示出来了。
细心的朋友会发现字体发生了变化,接下来设置字体,将字体相关文件也拖入到Assets文件夹下,然后修改一下podspec文件。最后执行pod install把字体资源pod进来。
修改FFSpecial.podspec文件如下:
s.resource_bundles = {
'FFSpecialKit' => ['FFSpecialKit/Assets/*']
}
执行完pod install
之后,字体资源就pod 进来了。
接着在原来设置字体的地方做相应的修改,和修改图片资源路径的方式相似。例如修改FFSpecialCell中的代码如下,通过加载bundle路径的方式加载字体。当然,因为有很多的地方都会用到,最好也抽取成工具类。
- (UILabel *)categoryLabel{
if (_categoryLabel == nil) {
_categoryLabel = [[UILabel alloc]init];
NSBundle *currentBundle = [NSBundle bundleForClass:[self class]];
NSString *path = [currentBundle pathForResource:@"CODE BOLD.OTF" ofType:nil inDirectory:@"FFSpecialKit"];
[_categoryLabel text:nil textColor:kHexColor_c7a762 fontSize:FONT_SIZE_14 fontName:path];
}
return _categoryLabel;
}
- (UILabel *)titleLabel{
if (_titleLabel == nil) {
_titleLabel = [[UILabel alloc]init];
NSBundle *currentBundle = [NSBundle bundleForClass:[self class]];
NSString *path = [currentBundle pathForResource:@"CODE LIGHT.OTF" ofType:nil inDirectory:@"FFSpecialKit.bundle"];
[_titleLabel text:nil textColor:kHexColor_555 fontSize:FONT_SIZE_14 fontName:path];
}
return _titleLabel;
}
- (UILabel *)descLabel{
if (_descLabel == nil) {
_descLabel = [[UILabel alloc]init];
NSBundle *currentBundle = [NSBundle bundleForClass:[self class]];
NSString *path = [currentBundle pathForResource:@"CODE LIGHT.OTF" ofType:nil inDirectory:@"FFSpecialKit.bundle"];
[_descLabel text:nil textColor:kHexColor_555 fontSize:FONT_SIZE_12 fontName:path];
_descLabel.numberOfLines = 2;
}
return _descLabel;
}
到这里都修改完后,再次运行就ok了。
后记
笔者通上、中、下三篇文章叙述了iOS项目实现组件化的一个大概流程。很感谢大家的阅读,也希望对您有所帮助。当然,如果对您没有帮助,浪费了您宝贵,笔者深感抱歉。第一次在上写技术文章,笔者小学语文没有学好,语言组织匮乏,希望各位多多指点。相互交流、相互成长。