在运行时知道您在IBDesignable

时间:2016-02-23 09:29:26

标签: ios xcode swift2 interface-builder

(在swift 2中编程)

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

问题是这些视图中的一个在初始化时执行代码,如果它仅在IBDesignable接口构建器的上下文中运行(仅执行以呈现IB屏幕),则执行断言。断言的原因是有效的,并且无关紧要,最重要的是我不想在“正常”操作期间放弃此功能。

我对解决方案的想法是知道什么时候执行代码只是为了在IB中为IBDesignable模式进行渲染,从而构建一个切换到/不执行断言。

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

我还考虑过使用prepareForInterfaceBuilder(),但这不适用,因为抛出断言的类与UIView本身没什么关系。

是否有一种函数或任何其他方法来检查AT RUNTIME(在框架中)您的代码是作为IB屏幕呈现的一部分运行的IBDesignable模式?

2 个答案:

答案 0 :(得分:3)

在测试了几十个解决方案后,我发现以下内容可靠地运行:

/**
 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
}

答案 1 :(得分:1)

SWIFT 4版

    /**
     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 = Bundle.main.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.contains("com.apple.")
    }