I have a simple UIButton
subclass that implements IBDesignable
with an IBInspectable
var:
@IBDesignable class Button: UIButton {
@IBInspectable var borderColor: UIColor = UIColor.whiteColor() {
didSet { layer.borderColor = borderColor.CGColor }
}
}
I am not using this within a framework and it is working in Interface Builder as intended, however, once I add this subclass to my Tests
target, it stops rendering live and I get the following errors:
Main.storyboard: error: IB Designables: Failed to update auto layout status: dlopen(TestTests.xctest, 1): Library not loaded: @rpath/XCTest.framework/XCTest
Referenced from: TestTests.xctest
Reason: image not found
Main.storyboard: error: IB Designables: Failed to render instance of Button: dlopen(TestTests.xctest, 1): Library not loaded: @rpath/XCTest.framework/XCTest
Referenced from: TestTests.xctest
Reason: image not found
If I remove IBDesignable
and the IBInspectable
vars, the errors go away - unfortunately so does the live rendering in Interface Builder.
How do I test against an IBDesignable
class without these errors?
At first, I thought this was a kind of bug in Xcode. Following is the workaround I found:
STEP 1
Mark your class and properties as public
.
@IBDesignable public class Button: UIButton {
@IBInspectable public var borderColor: UIColor = UIColor.whiteColor() {
didSet { layer.borderColor = borderColor.CGColor }
}
@IBInspectable public var borderWidth:CGFloat = 0.0 {
didSet { layer.borderWidth = borderWidth }
}
}
STEP 2
Import your application module from your "Tests" module.
For example, assuming that your application is named MyGreatApp
, in your MyGreatAppTests/MyGreatAppTests.swift
:
import UIKit
import XCTest
import MyGreatApp
class MyGreatAppTests: XCTestCase {
func testExample() {
let btn = Button()
btn.borderColor = UIColor.redColor()
XCTAssertEqual(UIColor(CGColor:btn.layer.borderColor), UIColor.redColor(), "borderColor")
}
}
You don't need to add 'Button.swift' to your "Tests" target.
STEP 3 (for Swift)
In your storyboard explicitly select the module MyGreatApp for any custom classes instead of letting Xcode use the current module.