webentwicklung-frage-antwort-db.com.de

IBDesignable-Fehler beim Hinzufügen zu einem Testziel

Ich habe eine einfache UIButton-Unterklasse, die IBDesignable mit einer IBInspectable var implementiert:

@IBDesignable class Button: UIButton {
    @IBInspectable var borderColor: UIColor = UIColor.whiteColor() {
        didSet { layer.borderColor = borderColor.CGColor }
    }
}

Ich verwende dies nicht in einem Framework und es funktioniert wie vorgesehen im Interface Builder. Sobald ich diese Unterklasse meinem Tests-Ziel hinzugefügt habe, wird die Wiedergabe nicht mehr live und ich erhalte die folgenden Fehler:

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

Wenn ich IBDesignable und die IBInspectable vars entferne, verschwinden die Fehler - leider auch das Live-Rendering im Interface Builder.

Wie teste ich gegen eine IBDesignable-Klasse ohne diese Fehler?

20
Adolfo

Zuerst dachte ich, das wäre eine Art Fehler in Xcode. Im Folgenden finden Sie die Problemumgehung, die ich gefunden habe:

SCHRITT 1

Markieren Sie Ihre Klasse und Ihre Eigenschaften als 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 }
    }
}

SCHRITT 2

Importieren Sie Ihr Anwendungsmodul aus Ihrem "Tests" -Modul. 

Nehmen Sie beispielsweise an, dass Ihre Anwendung MyGreatApp in Ihrem MyGreatAppTests/MyGreatAppTests.Swift heißt:

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")
    }
}

Sie müssen "Button.Swift" nicht zu Ihrem "Test" -Ziel hinzufügen.

SCHRITT 3 (für Swift)

Wählen Sie in Ihrem Storyboard explizit das Modul MyGreatApp für benutzerdefinierte Klassen aus, anstatt dass Xcode das aktuelle Modul verwendet.

Interface Builder select main target module

17
rintaro

Ihre Frage beschreibt genau die Umstände, die ich erlebt habe. Der Fehler ist auch im Attribut-Inspector unter Ihren eigenen Attributen sichtbar.

Dies ist die Problemumgehung, die für mich funktioniert hat:

Schritt 1 Entfernen Sie alle @IBDesignable und @IBInspectable aus Ihrem Quellcode

Schritt 2 Kehren Sie zum Interface Builder zurück. Der Fehler ist immer noch da. 

Schritt 3 Starten Sie XCode neu, erstellen Sie Ihr Projekt neu. Fehler sollten verschwunden sein.

Schritt 4 Füge alle @IBDesignable und @IBInspectable erneut zu deinem Quellcode hinzu

Nach diesen Schritten konnte ich mein Projekt problemlos weiterführen.

Meine Theorie, warum dies funktioniert, ist, dass der Schnittstellen-Builder etwas zwischenspeichert, das nicht gelöscht wird (und später erneut erstellt wird), wenn Sie ein Projekt -> Bereinigen ausführen.

Die andere Antwort (Importieren Ihres Hauptmoduls in Ihr Testmodul) ist eine gute Idee und löste einige böse Probleme für mich in der Vergangenheit, aber nicht dieses.

15
Gerd Castan

Die Lösung ist sehr einfach. Sie müssen Ihr Testziel entfernen und es von Anfang an erneut erstellen. Als ich das Projekt auf Xcode 7 verschoben hatte, wurde ich gewarnt, dass mein Testziel beschädigt ist. Also beschloss ich, es noch einmal einzurichten. ES ARBEITET! .

Außerdem hängen Sie Ihre Storyboards und auch keine Klasse an Ihr Testziel an. Bitte mach es nicht so:

 enter image description here

Tun Sie es stattdessen so:

 enter image description here

Entfernen Sie einfach eine beliebige Datei aus Ihrem Testziel (einschließlich Klassen mit @IBDesignables). Wenn Sie Zugriff auf Ihre Klassen innerhalb Ihres Testziels benötigen, verwenden Sie einfach @testable import MyApp:

 enter image description here

Es funktioniert und alle Fehler mit IBDesignables werden ausgeblendet. Genießen:-)

Was verursacht das?

Dieser Fehler tritt auf, wenn zwei Dinge passieren:

  1. Sie fügen eine beliebige Datei mit @IBDesignable oder @IBInspectable in Ihr Testziel ein.
  2. Sie öffnen Ihre .storyboard- oder .xib-Datei (die Ihre gestaltbaren/inspizierbaren Ansichten enthält).

Wie kann ich das verhindern?

Entweder:

  1. Schließen Sie keine Dateien mit @IBDesignable oder @IBInspectable in Ihr Testziel ein. (Wenn Sie nur einige isolierte Modelldateien testen, können sie Mitglieder Ihres Testziels bleiben.)
  2. Entfernen Sie alle Dateien Ihrer App aus Ihrem Testziel (wie in Antwort von Bartłomiej dargestellt) und stattdessen importieren Sie das App-Modul in Ihre Testdatei (zB @testable import MyAppsiehe hier für weitere Details .) Dies ist die bewährte Methode, mit der Sie Ihre entworfenen/inspizierbaren Ansichten sowie den Modellcode in Ihrer App weiterhin testen können.

Wie kann ich es lösen, wenn es schon passiert ist?

Das Ärgerliche an diesem Fehler ist, dass er nicht automatisch entfernt wird, sobald das Problem gelöst ist. Möglicherweise wird IB etwas zwischenspeichern, wie Gerd in seiner Antwort vorschlägt .

Ich habe festgestellt, dass, sobald Sie eine der beiden oben genannten vorbeugenden Maßnahmen durchgeführt haben, der Neustart von Xcode (ohne Änderung von Code) den Fehler beseitigt.

2
George WS

Endlich habe ich die Lösung gefunden. Fügen Sie Ihrem Testziel unter Build Settings/andere Linker-Flags "-framework XCTest" hinzu.

1
CZ54

Dieses Problem kann auch dadurch verursacht werden, dass Kategorien oder Erweiterungen der Ansichtsklasse in Ihr Testziel aufgenommen werden.

0
Brian Croom