一个笔尖,不同的资产。捆绑?

时间:2009-02-11 21:21:42

标签: iphone cocoa-touch xcode interface-builder target

我有一个iPhone应用程序,它有不同的皮肤风格,具有不同的艺术资产和声音,但所有相同的代码。

我已经设置了多个目标,但我遇到的问题是我必须有一组不同的UIBuilder nib文件,每个目标每个视图一个,设置为指向正确的艺术目标

这有点令人沮丧,因为如果我对一个nib文件进行更改,我必须在所有其他nib文件中手动进行相同的更改,相同的连接等。我还为不同的皮肤添加了不同名称的所有资源,因此它们不会在项目中发生冲突。所以,如果我有目标A和B,我有a_main_menu.pngb_main_menu.png ... a_FooViewController.xibb_FooViewController.xib等等。

有没有办法制作一个nib文件,指向具有相同名称的资产,但是在......嗯,不同的捆绑包?捆绑是什么?我可以想象在我的代码中修复这样的东西(可能在加载它之前在nib中搜索和替换A可能就足够了),虽然我没有尝试过,但这很难看。

对于我的第一组应用程序来说,这是一个可管理的策略(虽然远非最佳),但随着我的东西变得越来越复杂,我的构建器文件保持同步变得非常困难,而且这种方式并不是很干净。工作。除了放弃uibuilder并在代码中创建我的观点之外,还有更好的方法吗?

如果这在xcode / builder级别工作会很好,所以构建器会尊重我当前的目标,并在我工作时展示该目标的艺术......但我可以没有那样生活,就像我可以在运行时选择当前的艺术作品,我只能在构建器中使用一组。我也可以通过一个目标并在构建之前手动替换所有艺术品来完成一组笔尖,但这也不是很好。

最重要的是,如果我可以混合使用这两种策略 - 比如我有一个目标,其中有一个具有一个视图,而这些视图只是以不同的方式布局......但这是可选的。

我问的是正确的问题吗?

谢谢!

5 个答案:

答案 0 :(得分:5)

执行此操作的一种方法是将所有图稿移动到单独的捆绑包中,并在运行时动态加载它(有点像“媒体插件”)。

  • 创建一个单独的项目,然后选择“Mac OS X / Framework& Library / Bundle”。比如说,media.bundle

  • 将您的所有作品移动到此项目中。

  • 为了简化生活,请向目标添加一个额外的“运行脚本”步骤,将构建目录中的构建输出复制到主项目下的子文件夹中。为了使其更加简单,请将媒体包添加为主项目中的依赖项目,以便自动重建。

在您的主项目中,您将需要这两种方法。您可以在BundleUtils类:

下创建静态方法
+ (NSString *) bundleDirectoryFor:(NSString *) bundleName
{
 NSString* basePath = [[[NSBundle mainBundle] resourcePath]
     stringByAppendingPathComponent:[NSString
                                stringWithFormat:@"%@.bundle", bundleName]];
 return [[NSBundle bundleWithPath:basePath] resourcePath];
}

+ (NSString *) resourceInBundle:(NSString *)bundleName 
                       fileName:(NSString *)fileName
{
 NSString *bundlePath = [BundleUtils bundleDirectoryFor:bundleName];
 return [bundlePath stringByAppendingPathComponent:fileName];
}

现在,每当您想要访问捆绑包中的图片时,您都可以通过以下方式获取正确文件的路径:

NSString* imageFile = [BundleUtils resourceInBundle:@"media.bundle" 
                                        fileName:@"image.jpg"];
UIImage* image = [UIImage imageNamed:imageFile];

显然,名称“media.bundle”可以在运行时替换为另一个名称,因此您可以根据应用程序的需要切换到其他捆绑包。这也是支持可下载内容的便捷方式(例如,作为付费附加组件)。

有一点需要注意:这假设您需要在运行时通过代码动态加载图像。但是,您还有静态NIB文件,其中嵌入了媒体。您必须找到一种方法来使静态NIB文件使用动态方法来解析媒体文件名。一种方法是使用MethodSwizzling并注意具有类型前缀的文件路径,例如“media:image.png”并重定向它们以使用BundleUtil方法。

另一种方法是使用IB进行布局,然后使用nib2objc将其转换为Obj-C代码,然后替换插件包机制。

希望这有帮助。

答案 1 :(得分:1)

假设每个应用程序一次只需要一个皮肤,并且您正在创建具有不同主题的多个应用程序,我将在源代码管理中创建一个分支,然后替换必要的资产。保留一个包含所有默认资产的主分支,然后将代码更改从主服务器合并到您的分支机构中,使所有内容保持同步。

Git让这非常容易。

答案 2 :(得分:0)

我认为最好的选择是使用像git这样的东西。

如果您使用git,您可以拥有一个包含主源代码和逻辑的主分支,并且具有针对您的应用程序的每种特定风格具有不同数据/图像集的子分支。在这个解决方案中,XCode甚至不知道发生了什么。

答案 3 :(得分:0)

我认为这就是viewDidLoad的用途,为了自定义更多,在这里你可以改变图像路径。

答案 4 :(得分:0)

这对我有用:

1个项目。 2目标a,b。 a,b。

的2个图像文件夹

controller.m及其nib文件适用于两个目标。

为目标a和b的图像创建单独的文件系统文件夹。

导入一个图像文件夹以定位a(“将文件添加到xy” - >“添加到目标a / b”),另一个导向目标b。确保使用“为添加的文件夹创建组”选项。不要选择“文件夹引用”选项。

当我构建目标a时,我得到一个带有来自文件夹a的图像的应用程序;当我为b构建时,它使用文件夹b作为图片。