IBDesignable从外部框架?
我想创build一些使用@IBDesignable
和@IBInspectable
标签的自定义视图。 我已经将这些添加到我的框架,然后将我的框架链接到我的testing应用程序。 但是Designables从来没有出现在StoryBoard中。
我如何使用@IBDesignable
和@IBInspectable
从外部框架创build自定义视图?
你可以在非embedded式框架的应用程序中使用@IBDesignable
和@IBInspectable
吗?
谢谢。
我find了一种使用Cocoa Touch框架devise和检查的方法。 下面的说明适用于Objective-C项目和Xcode 8(我没有在老版本上testing),如果涉及到Swift代码,应该是相同的。
由于Interface Builder在框架中没有发现可devise的元素,因此在框架头文件IB_DESIGNABLE
类标记为IB_DESIGNABLE
是没有用的。 Interface Builder只在编译项目源文件时才会发现可devise的类。 因此,这个想法是将这些信息作为框架伴随源文件提供给客户,然后客户就可以用他们的项目进行编译。
我发现你不必在子项目中标记一个框架类是可devise的。 您可以简单地注释每个必须通过伴随.m
源文件中声明的类别devise的类,例如:
IB_DESIGNABLE @interface MyCustomView (Designable) @end
事实上,代码甚至不需要编译,你可以把它封装在一个封闭的#if 0 ... #endif
,它仍然可以工作。 所有需要的是该类在某种程度上与IB_DESIGNABLE
属性相关联。
牢记这些信息,以下是如何使可devise的框架与cocoa触摸框架一起工作:
如果你是一个框架供应商:
- 如果需要,有必须devise的组件实现
-prepareForInterfaceBuilder
- 将文件夹引用(蓝色文件夹)添加到您的框架目标,其中伴随
.m
文件。 一个可能的命名约定是命名文件夹Designables
和Designables
文件,但是你可以select你最喜欢的任何东西。 - 在
.m
文件中,为每个必须可devise的视图创build一个类似上面的类别。 文件本身必须可以由客户端项目编译,这意味着你要么需要进行必要的导入(例如你的框架全局公共头文件#import <MyFramework/MyFramework.h>
),或者使用#if 0 ... #endif
技巧
通过将文件封装在蓝色文件夹中,我们确保该文件夹被复制到最终的.framework
产品中,而不会编译伴随源文件。 而且,由于该文件夹是框架包的一部分,因此它可以被框架的所有客户端使用,无论它们是直接整合还是使用Carthage。
如果您有一个使用框架作为目标依赖项的演示项目,并且您的框架依赖于其他框架,则在演示项目中尝试呈现可devise视图时,将遇到dlopen
问题。 这是因为在框架目标中发现了IB_DESIGNABLE
属性(因为已经添加了Designables
文件夹),该Xcode预先在对应于您的项目的Build/Intermediates/IBDesignables
派生数据文件夹中Build/Intermediates/IBDesignables
。 如果你看看这个文件夹的内容,框架依赖关系就会丢失,导致dlopen
问题。
要修复演示中的渲染,只需将“ 复制文件”阶段添加到框架目标,将所需的每个框架依赖项添加到文件列表,并将Products目录设置为目标。 现在,当Xcode构build您的演示演示,它也将包括依赖关系。
如果您是具有可devise支持的框架的用户:
- 将框架(及其所有框架依赖关系,如果有的话)作为embedded式二进制添加到您的目标
- 从框架包中检索伴随源文件并将其复制到您的项目中,并将其添加到您的目标中。 添加位于框架内的文件或者使用符号链接是不合适的,因为Xcode似乎根本不在框架之内
- 添加一个可devise的视图类(在我们上面的例子中的
MyCustomView
)的一个实例到故事板。 界面生成器应该构build项目并呈现视图
此解决scheme并不完美,因为您仍然需要手动复制所提供的源文件,这可能会在不同的框架版本之间进行更改。 但是,它工作得很好,并且提供了框架包本身所需的一切。
我有一个解决方法。 有了这个解决方法,你不需要添加框架作为目标。 所以它适用于迦太基 。
@IBDesignable class MyCustomView: CustomView { @IBInspectable override var bgColor: NSColor { get { return super.bgColor } set { super.bgColor = newValue } } }
在目标项目(不在框架项目中)中创build自定义类( CustomView
)的子类( MyCustomView
),并将该子类标记为@IBDesignable。 在你的应用程序中使用子类。 这样使@IBDesignable工作。
在子类中,覆盖这些@IBInspectable属性( bgColor
),这样使得@IBInspectable可以工作。
您可能会遇到此问题: 从IBDesignable中的自定义控件的框架加载代码按照本指南解决此问题: http : //www.dribin.org/dave/blog/archives/2009/11/15/rpath/
并且请将自定义类和其可检查的属性都公开,否则此方法不能编译。
请留下评论,如果你不能得到它的工作。
好吧,显然如果你想在framework
包含@IBDesignabl
和@IBInspectable
, framework
必须是:
- 包含在消费应用程序中,所以
Framework
将不会在它自己的项目中。 (即从消费应用程序执行诸如'file -> new.. -> target -> framework'
的框架作为目标)。 - 将
external framework
作为CocoaPod
在消费应用程序中。 这实际上增加了framework
作为目标,而不是仅仅将framework
与应用程序连接起来。- 有一种方法可以在一个项目中包含本地的
CocoaPods
,所以不用担心,你不必为了这个目的而将你的framework
部署到公共场所。
- 有一种方法可以在一个项目中包含本地的
编辑 :泰勒长有Carthage
的工作。 看看他的答案。