UIButton
とIBDesignable
varを実装する単純なIBInspectable
サブクラスがあります。
@IBDesignable class Button: UIButton {
@IBInspectable var borderColor: UIColor = UIColor.whiteColor() {
didSet { layer.borderColor = borderColor.CGColor }
}
}
私はこれをフレームワーク内で使用しておらず、意図したとおりにInterface Builderで機能していますが、このサブクラスをTests
ターゲットに追加すると、ライブレンダリングが停止し、次のエラーが発生します。
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
IBDesignable
とIBInspectable
varsを削除すると、エラーはなくなります。残念ながら、InterfaceBuilderでのライブレンダリングもなくなります。
これらのエラーなしでIBDesignable
クラスに対してテストするにはどうすればよいですか?
最初は、これはXcodeの一種のバグだと思いました。以下は私が見つけた回避策です:
ステップ1
クラスとプロパティを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 }
}
}
ステップ2
「テスト」モジュールからアプリケーションモジュールをインポートします。
たとえば、アプリケーションの名前がMyGreatApp
であるとすると、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")
}
}
「Tests」ターゲットに「Button.Swift」を追加する必要はありません。
ステップ(スイフト用)
ストーリーボードで、Xcodeに現在のモジュールを使用させるのではなく、カスタムクラスのモジュールMyGreatAppを明示的に選択します。
あなたの質問は、私が経験した状況を正確に説明しています。エラーは、独自の属性の下の属性インスペクターにも表示されます。
これは私のために働いた回避策です:
ステップ1ソースコードからすべての@IBDesignableと@IBInspectableを削除します
ステップ2 InterfaceBuilderに戻ります。エラーはまだあります。
ステップ XCodeを再起動し、プロジェクトを再構築します。エラーは消えるはずです。
ステップ4すべての@IBDesignableと@IBInspectableをソースコードに再度追加します
このステップの後、私は問題なくプロジェクトを進めることができました。
これが機能する理由は、[プロジェクト]-> [クリーン]を実行したときに、インターフェイスビルダーが削除されない(後で再構築される)ものをキャッシュするという私の理論です。
もう1つの答え(メインモジュールをテストモジュールにインポートする)は良い考えであり、過去に私にとっていくつかの厄介な問題を解決しましたが、これは解決しませんでした。
解決策は非常に簡単です。テストターゲットを削除し、最初からもう一度作成する必要があります。プロジェクトをXcode7に移動したときに、テストターゲットが破損しているという警告が表示されました。そこで、もう一度設定することにしました。 それはうまくいきました!。
さらに、ストーリーボードやクラスさえもテストターゲットに添付しません。このようにしないでください:
代わりに、次のようにしてください。
したがって、テストターゲット(@IBDesignablesのクラスを含む)からファイルを削除するだけです。テストターゲット内のクラスにアクセスする必要がある場合は、@testable import MyApp
を使用してください。
それは機能しており、IBDesignablesのすべてのエラーが消えます。楽しい:-)
これを引き起こしているのは何ですか?
このエラーは、次の2つの場合に発生します。
@IBDesignable
または@IBInspectable
を含むファイルをテストターゲットに含めます。これを防ぐにはどうすればよいですか?
どちらか:
@IBDesignable
または@IBInspectable
を含むファイルをテストターゲットに含めないでください。 (いくつかの分離されたモデルファイルをテストしているだけの場合、それらはテストターゲットのメンバーのままでかまいません。)@testable import MyApp
— 詳細はこちらをご覧ください 。)これはベストプラクティスであり、設計可能/検査可能なビューとモデルコードのテストを継続できます。アプリ内。それがすでに起こったらどうすれば解決できますか?
このエラーの厄介な点は、問題が解決された後は自動的に消えないことです。これは、IBが何かをキャッシュしている可能性があるためです Gerdは彼の回答で示唆しています 。
私が見つけたのは、上記の2つの予防策のいずれかを実際に実行した後、Xcodeを(コードを変更せずに)再起動するだけでエラーがなくなることです。
私はついに解決策を見つけました。ビルド設定/その他のリンカーフラグの下で、テストターゲットに「-frameworkXCTest」を追加してください。
この問題は、テストターゲットのビュークラスにカテゴリまたは拡張機能を含めることによっても発生する可能性があります。