IBDesignable来自外部框架?

Sak*_*boy 15 storyboard ios ios-frameworks swift ibdesignable

我想创建一些使用@IBDesignable@IBInspectable标签的自定义视图.我已将这些添加到我的框架中,然后将我的框架链接到我的测试应用程序.但是Designables从未出现在StoryBoard中.

如何使用@IBDesignable@IBInspectable从外部框架创建自定义视图?

您可以使用@IBDesignable,并@IBInspectable在从非嵌入式框架的应用程序?

谢谢.

def*_*gos 12

我找到了一种在Cocoa Touch框架中使用designables和inspectables的方法.下面的说明适用于Objective-C项目和Xcode 8(我没有在旧版本上测试),如果涉及Swift代码,则应该是相同的.

由于Interface Builder在框架中没有发现可设计,因此IB_DESIGNABLE在框架标题中标记类是没用的.Interface Builder将仅在编译项目源文件时发现可设计的类.因此,我们的想法是将此信息作为框架伴随源文件提供,然后客户端可以使用他们的项目进行编译.

我发现您不必将子类标记为可在项目中设计的框架类.您可以简单地注释每个必须通过伴随.m源文件中声明的类别设计的类,例如:

IB_DESIGNABLE
@interface MyCustomView (Designable)

@end
Run Code Online (Sandbox Code Playgroud)

实际上,代码甚至不需要编译,你可以将它包装在一个封闭中#if 0 ... #endif,它仍然可以工作.所需要的只是该类以某种方式与IB_DESIGNABLE属性相关联.

记住这些信息,以下是如何使可设计与Cocoa Touch框架一起使用:


如果您是框架供应商:

  1. 如果需要,有必须可设计的组件 -prepareForInterfaceBuilder
  2. 将文件夹引用(蓝色文件夹)添加到框架目标,其中包含配套.m文件.可能的命名约定是命名文件夹Designables及其中的文件 MyFrameworkNameDesignables.m,但您可以选择您最喜欢的任何内容.
  3. .m文件中,为每个必须可设计的视图创建类似上面的类别.文件本身必须由客户端项目编译,这意味着您需要进行必要的导入(例如您的框架全局公共标题#import <MyFramework/MyFramework.h>)或使用#if 0 ... #endif上面的技巧

通过将文件封装在蓝色文件夹中,我们确保将文件夹复制到最终.framework产品中,而不编译伴随源文件.此外,由于文件夹是框架包的一部分,它可供框架的所有客户使用,无论是直接集成还是使用Carthage.

如果您有一个使用框架作为目标依赖项的演示项目,并且如果您的框架依赖于其他框架,那么dlopen在尝试在演示项目中呈现可设计视图时会遇到问题.这是因为IB_DESIGNABLE在框架目标中发现了属性(因为Designables已经添加了文件夹),Xcode预先构建在与Build/Intermediates/IBDesignables项目对应的派生数据文件夹中.如果查看此文件夹的内容,则缺少框架依赖项,从而导致dlopen问题.

要在演示中修复渲染,只需将复制文件阶段添加到框架目标,将每个必需的框架依赖项添加到文件列表,并将Products目录设置为目标.现在,当Xcode构建用于渲染的演示时,它也将包含依赖项.


如果您是具有可设计支持的框架的用户:

  • 将框架(及其所有框架依赖项,如果有的话)作为嵌入式二进制文件添加到目标
  • 从框架包中检索伴随源文件并将复制到项目中,并将其添加到目标中.遗憾地添加位于框架内或使用符号链接的文件不起作用,因为Xcode似乎根本不在框架内查找
  • 将可设计视图类的实例(MyCustomView在上面的示例中)添加到故事板.Interface Builder应该构建项目并呈现视图

此解决方案并不完美,因为您仍然需要手动复制提供的源文件,这可能会在框架版本之间发生变化.但它运行得很好,并提供了框架包本身所需的一切.


Tyl*_*ong 8

我有一个解决方法.通过此解决方法,您无需将框架添加为目标.所以它适用于迦太基.

@IBDesignable
class MyCustomView: CustomView {

    @IBInspectable override var bgColor: NSColor {
        get {
            return super.bgColor
        }
        set {
            super.bgColor = newValue
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在目标项目(而不是框架项目)中创建MyCustomView自定义类(CustomView)的子类(),并将子类标记为@IBDesignable.在您的应用中使用子类.这种方式使@IBDesignable工作.

在子类内部,覆盖那些@IBInspectable属性(bgColor),这种方式使@IBInspectable工作.

您可能会遇到此问题:从IBDesignable中的自定义控件框架加载代码 按照本指南解决此问题:http://www.dribin.org/dave/blog/archives/2009/11/15/rpath/

请将自定义类及其可检查属性公开,否则此方法无法编译.

如果你不能正常工作,请留下评论.


Sak*_*boy 5

好了,所以很明显,如果你想包括@IBDesignable和@IBInspectableframeworkframework有两种是:

  • 包含在消费应用程序中,因此Framework不会在它自己的项目中。(即通过执行类似'file -> new.. -> target -> framework'消费应用程序的操作来添加框架作为目标)。
  • external frameworkas a包含CocoaPod在您的消费应用程序中。这实际上将 增加framework为目标,而不仅仅是将 链接framework到应用程序。
    • 有一种方法可以将本地包含CocoaPods在项目中,所以不用担心您不必framework为了执行此操作而将其部署到公众。


chr*_*nse 5

UICircularProgressRing通过@IBDesignable在框架Headers文件夹中添加包含类的 Swift 文件来解决这个问题。为此,选择框架的 Xcode 项目,选择框架的目标,然后转到Build Phases选项卡并展开Headers阶段,然后将 Swift 文件放入Public

Xcode Build Phases 选项卡的屏幕截图,显示了 Headers 阶段