J'ai une simple sous-classe UIButton
qui implémente IBDesignable
avec une IBInspectable
var:
@IBDesignable class Button: UIButton {
@IBInspectable var borderColor: UIColor = UIColor.whiteColor() {
didSet { layer.borderColor = borderColor.CGColor }
}
}
Je n'utilise pas cela dans un cadre et cela fonctionne dans Interface Builder comme prévu. Cependant, une fois que j'ajoute cette sous-classe à ma cible Tests
, elle arrête le rendu en direct et j'obtiens les erreurs suivantes:
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
Si je supprime IBDesignable
et les IBInspectable
vars, les erreurs disparaissent - malheureusement, le rendu en direct dans Interface Builder.
Comment tester contre une classe IBDesignable
sans ces erreurs?
Au début, je pensais que c'était une sorte de bogue dans Xcode. Voici la solution de contournement que j'ai trouvée:
ÉTAPE 1
Marquez votre classe et vos propriétés comme étant 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 }
}
}
ÉTAPE 2
Importez votre module d'application à partir de votre module "Tests".
Par exemple, en supposant que votre application s'appelle MyGreatApp
, dans votre 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")
}
}
Vous n'avez pas besoin d'ajouter 'Button.Swift' à votre cible "Tests".
ÉTAPE 3 (pour Swift)
Dans votre storyboard, sélectionnez explicitement le module MyGreatApp pour toute classe personnalisée au lieu de laisser Xcode utiliser le module actuel.
Votre question décrit exactement les circonstances que j'ai vécues. L'erreur est également visible dans l'inspecteur d'attributs sous vos propres attributs.
Voici la solution de contournement qui a fonctionné pour moi:
Étape 1 Supprimez tous les @IBDesignable et @IBInspectable de votre code source.
Étape 2 Retournez au constructeur d'interfaces. L'erreur est toujours là.
Étape 3 Redémarrez XCode, reconstruisez votre projet. Les erreurs doivent être effacées.
Étape 4 Ajoutez tous les @IBDesignable et @IBInspectable à votre code source.
Après cette étape, j'ai pu poursuivre mon projet sans aucun problème.
Ma théorie explique pourquoi cela fonctionne, c'est que le constructeur d'interface met en cache des éléments qui ne sont pas supprimés (et reconstruits ultérieurement) lorsque vous effectuez un projet -> nettoyer.
L’autre réponse (importer votre module principal dans votre module de test) est une bonne idée et a permis de résoudre certains problèmes désagréables dans le passé, mais pas celui-ci.
La solution est très simple. Vous devez supprimer votre cible de test et la recréer depuis le début. Lorsque j'ai déplacé le projet vers Xcode 7, j'ai été averti que ma cible de test était endommagée. Alors j'ai décidé de le mettre en place une fois de plus. CELA A FONCTIONNÉ! .
De plus, vous n’attachez ni vos storyboards, ni même une classe à votre cible de test. S'il vous plaît ne le faites pas comme ça:
Au lieu de cela, faites-le de cette façon:
Donc, supprimez simplement tout fichier de votre cible de test (y compris les classes avec @IBDesignables), puis si vous avez besoin d'accéder à vos classes dans votre cible de test, utilisez simplement @testable import MyApp
:
Cela fonctionne et toutes les erreurs avec IBDesignables disparaîtront. Prendre plaisir:-)
Qu'est-ce qui cause ça?
Cette erreur apparaît lorsque deux événements se produisent:
@IBDesignable
ou @IBInspectable
dans votre cible de test.Comment puis-je empêcher cela?
Non plus:
@IBDesignable
ou @IBInspectable
dans votre cible de test. (Si vous testez simplement quelques fichiers de modèle isolés, ils peuvent rester membres de votre cible de test.)@testable import MyApp
— voir ici pour plus de détails .) Il s'agit de la meilleure pratique, vous permettant de continuer à tester vos vues pouvant être désignées/inspectables ainsi que tout code de modèle de votre application. Comment puis-je le résoudre une fois que c'est déjà arrivé?
Le problème avec cette erreur est qu’elle ne disparaît pas automatiquement une fois le problème résolu, car IB risque de mettre en cache quelque chose comme Gerd suggère dans sa réponse .
Ce que j’ai trouvé, c’est qu’une fois que vous avez effectivement appliqué l’une des deux mesures préventives énumérées ci-dessus, le simple redémarrage de Xcode (sans modification de code) devrait faire disparaître l’erreur.
J'ai finalement trouvé la solution. Ajoutez juste "-framework XCTest" à votre cible de test sous Paramètres de construction/autres drapeaux de l'éditeur de liens.
Ce problème peut également être causé par l'inclusion de catégories ou d'extensions dans la classe de vue de votre cible de test.