在运行时知道您正在 IBDesignable 中运行

Hix*_*eld 6 xcode interface-builder ios swift2

(在swift 2中编程)

在我的 iOS 应用程序中,我使用了框架。我也在使用 IBDesignable 功能取得了巨大成功。我在 IBDesignable 框架中有一堆视图和按钮,因此可以在界面构建器的屏幕上很好地呈现。

问题是这些视图之一在初始化时执行代码,如果它仅在 IBDesignable interfacebuilder 的上下文中运行(仅执行以呈现 IB 屏幕),则该代码将执行断言。断言的原因是有效的,实际上并不重要,最重要的是我不想在“正常”操作期间失去此功能。

我对解决方案的想法是知道何时执行代码只是为了在 IB 中呈现 IBDesignable 模式,从而构建一个不/不执行断言的开关。

我尝试使用 #if !TARGET_INTERFACE_BUILDER 但这不起作用,因为这是一个预处理器指令,因此只评估编译时间,并且框架是预编译的(在实际应用程序中使用时)。

我也考虑过使用 prepareForInterfaceBuilder() 但这并不适用,因为抛出断言的类与 UIView 本身无关。

是否有函数或任何其他方法可以在运行时(在框架中)检查您的代码是否作为 IBDesignable 模式的 IB 屏幕渲染的一部分运行?

Hix*_*eld 5

在测试了几十个解决方案后,我发现以下方法可以可靠地工作:

/**
 Returns true if the code is being executed as part of the Interface Builder IBDesignable rendering,
 so not for testing the app but just for rendering the controls in the IB window. You can use this
 to do special processing in this case.
*/
public func runningInInterfaceBuilder() -> Bool {
    //get the mainbundles id
    guard let bundleId = NSBundle.mainBundle().bundleIdentifier else {
        //if we don't have a bundle id we are assuming we are running under IBDesignable mode
        return true
    }
    //when running under xCode/IBDesignable the bundle is something like
    //com.apple.InterfaceBuilder.IBCocoaTouchPlugin.IBCocoaTouchTool
    //so we check for the com.apple. to see if we are running in IBDesignable rendering mode
    //if you are making an app for apple itself this would not work, but we can live with that :)
    return bundleId.rangeOfString("com.apple.") != nil
}
Run Code Online (Sandbox Code Playgroud)