首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >来自外部框架的IBDesignable?

来自外部框架的IBDesignable?
EN

Stack Overflow用户
提问于 2015-04-29 03:15:23
回答 4查看 6.3K关注 0票数 17

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

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

您能在非嵌入式框架的应用程序中使用@IBDesignable@IBInspectable吗?

谢谢。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2016-10-12 13:28:58

我找到了一种使用Cocoa框架的可设计性和可检查性的方法。下面的说明是针对Objective项目和Xcode 8的(我没有在旧版本上进行测试),如果涉及Swift代码的话,应该是相同的。

由于框架中的Interface没有发现可设计性,所以在框架头中将类标记为IB_DESIGNABLE是无用的。接口生成器只会在编译项目源文件时发现可设计类。因此,我们的想法是将这些信息作为一个框架辅助源文件提供,然后客户端可以使用他们的项目进行编译。

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

代码语言:javascript
复制
IB_DESIGNABLE
@interface MyCustomView (Designable)

@end

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

考虑到这些信息,下面是如何使可设计性与Cocoa框架一起工作:

如果您是框架供应商的话,

  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问题。

要修复演示中的呈现,只需向框架目标添加一个Copy阶段,将每个必需的框架依赖项添加到文件列表中,并将Products目录设置为目标。现在,当Xcode构建用于呈现的演示时,它还将包括依赖项。

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

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

这个解决方案并不完美,因为您仍然需要手动复制提供的源文件,这可能会在框架版本之间发生更改。但是,它工作得很好,提供了框架包本身中所需的一切。

票数 13
EN

Stack Overflow用户

发布于 2016-06-04 15:21:25

我有个解决办法。有了这个解决办法,您不需要将框架作为目标添加。因此,它适用于迦太基

代码语言:javascript
复制
@IBDesignable
class MyCustomView: CustomView {

    @IBInspectable override var bgColor: NSColor {
        get {
            return super.bgColor
        }
        set {
            super.bgColor = newValue
        }
    }
}

在目标项目(而不是框架项目)中创建自定义类(MyCustomView)的子类(MyCustomView),并将子类标记为@IBDesignable。在应用程序中使用子类。这样可以使@IBDesignable工作。

在子类中,重写那些@IBInspectable属性(bgColor),这样可以使@IB了无障碍工作。

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

并且请将自定义类及其可检查属性公开,否则此方法不会编译。

如果你不能让它工作,请留下评论。

票数 9
EN

Stack Overflow用户

发布于 2015-04-30 20:38:49

好吧,很显然,如果你想把@IBDesignable和@IBInspectable包括在framework中,framework必须是:

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

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29933691

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档