IB_DESIGNABLE, IBInspectable - Il generatore di interfacce non si aggiorna


91

Ho il seguente set di codice:

CustomView.h

#import <UIKit/UIKit.h>

IB_DESIGNABLE
@interface CustomView : UIView

@property (nonatomic) IBInspectable UIColor *borderColor;
@property (nonatomic) IBInspectable CGFloat borderWidth;
@property (nonatomic) IBInspectable CGFloat cornerRadius;

@end

CustomView.m

#import "CustomView.h"

@implementation CustomView

- (void)setBorderColor:(UIColor *)borderColor {
    _borderColor = borderColor;
    self.layer.borderColor = borderColor.CGColor;
}

- (void)setBorderWidth:(CGFloat)borderWidth {
    _borderWidth = borderWidth;
    self.layer.borderWidth = borderWidth;
}

- (void)setCornerRadius:(CGFloat)cornerRadius {
    _cornerRadius = cornerRadius;
    self.layer.cornerRadius = cornerRadius;
}

@end

(Per riferimento Swift, questo problema si verificava anche con il codice Swift)

CustomView.swift

@IBDesignable
class CustomView : UIView {
    override init(frame: CGRect) {
        super.init(frame: frame)
    }

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    @IBInspectable var borderColor : UIColor = UIColor.clearColor() {
        didSet {
            self.layer.borderColor = borderColor.CGColor
        }
    }

    @IBInspectable var borderWidth : CGFloat = 0.0 {
        didSet {
            self.layer.borderWidth = borderWidth
        }
    }

    @IBInspectable var cornerRadius : CGFloat = 0.0 {
        didSet {
            self.layer.cornerRadius = cornerRadius
        }
    }
}

Ho aggiunto un UIViewa un controller di visualizzazione sullo storyboard e ho impostato la sua sottoclasse su CustomView.

inserisci qui la descrizione dell'immagine

Ciò aggiunge la riga "Designables". È bloccato su "Aggiornamento" e la descrizione comando dice "In attesa di creazione del target". Non cambia mai da questo stato.

Quando passo alla verifica degli attributi, posso impostare queste IBInspectableproprietà:

inserisci qui la descrizione dell'immagine

E una volta impostati, vengono visualizzati anche negli "Attributi di runtime definiti dall'utente":

inserisci qui la descrizione dell'immagine

Tuttavia, lo stato "Designabili" non va mai oltre "Aggiornamento" con sempre lo stesso suggerimento (ho provato a compilare Cmd + B più volte, non cambia nulla).

Inoltre, mentre imposto le IBInspectableproprietà, ricevo un avviso per ognuna:

IBDesignables - Ignorando l'attributo di runtime definito dall'utente per il percorso della chiave "borderColor" sull'istanza di "UIView" ... questa classe non è conforme alla codifica del valore-chiave per la chiave borderColor.

Screenshot degli avvisi generati:

inserisci qui la descrizione dell'immagine


Conosco i problemi relativi alla codifica di valori-chiave e generalmente so come risolverli ... ma non capisco come risolvere questo problema qui. Secondo l'ispettore identità della vista, la vista è una "CustomView" (non una normale "UIView", che non ha queste proprietà). E se la vista non fosse una "Visualizzazione personalizzata", queste proprietà progettabili non sarebbero visualizzate nell'ispettore degli attributi, giusto? Ma quando Interface Builder tenta di applicare questi attributi alla vista, torna a pensare che la classe della vista sia "UIView" e non può applicare gli attributi.

Qualsiasi aiuto? Per favore fatemi sapere se ho tralasciato alcuni dettagli importanti, ma per quello che vale, ho seguito esattamente questo tutorial (diverso da ObjC vs Swift). Vale anche la pena notare che ho seguito questo tutorial esattamente su un'altra macchina e ha funzionato a meraviglia (intendevo fare questo post ieri sera ma il computer su cui ero allora non aveva questo problema).


Sulla base dei commenti, è stato suggerito che forse il .mfile non è incluso e che potrebbe essere la causa del problema. Ho pensato che sicuramente avrei fatto di tutto per questo scenario, ma ho controllato comunque.

inserisci qui la descrizione dell'immagine

Quando ho iniziato a tentare di farlo, ero consapevole che le IB_DESIGNABLEclassi dovevano far parte di un diversoUIKit quadro . Quindi, da questo primo screenshot, si può vedere che ho creato un quadro "CustomViews", che ha una classe, CustomView. Vedrai anche qui che ho anche creato un OtherView, che è identico a CustomView, tranne che non è in un framework separato. Lo stesso problema persiste nello storyboard tra le due classi.

Qui abbiamo uno screenshot che indica che CustomView.mè incluso per essere compilato conCustomViews framework:

inserisci qui la descrizione dell'immagine

Nel frattempo, la seguente schermata indica diverse cose:

  • CustomViews.framework è opportunamente incluso nel progetto principale.
  • OtherView.mè incluso anche come sorgente di compilazione, quindi anche se qualcosa non va CustomView,OtherView dovrebbe funzionare, tuttavia genera errori identici.
  • Main.storyboarde LaunchScreen.xibvengono visualizzati come rossi. Non ho idea del perché, e non ho la minima idea del perché LaunchScreen.xibdovrebbe (non ho toccato questo file), anche se posso dire dopo aver guardato altri progetti, Main.storyboardappare anche in rosso per quei progetti, e sono non fare nulla con IB_DESIGNABLEo IBInspectablelì.

inserisci qui la descrizione dell'immagine


Ho provato e riprovato diverse volte. Funziona ogni volta sul mio computer a casa - non posso riprodurre il problema descritto in questa domanda a casa. Al lavoro, non funziona mai. Il problema descritto in questa domanda si verifica ogni volta.

Entrambi i computer sono Mac Mini acquistati nuovi quest'anno (non i nuovi modelli, modello di fine 2012). Entrambi i computer eseguono OS X Yosemite 10.10. Entrambi i computer eseguono Xcode versione 6.1. A casa, la build è (6A1052d). Questa mattina, posso confermare che entrambi i computer eseguono build identiche di Xcode.

Altri mi hanno suggerito che potrebbe essere una cattiva RAM. Mi sembra inverosimile. Ho riavviato il progetto più volte, riavviato il computer più volte. Mi sembra che se ci fosse una cattiva RAM su un computer di circa 6 mesi, vedrei altri problemi e questo problema sarebbe meno consistente. Ma questo problema esatto persiste nonostante numerose volte il riavvio dell'intero progetto da zero e il riavvio completo sul computer.


Vale la pena notare che se compilo ed eseguo effettivamente questo progetto, la visualizzazione personalizzata con le IBInspectableproprietà viene effettivamente visualizzata come mi aspetto che lo storyboard lo visualizzi. Immagino che questo sarebbe il caso anche senza le direttive IB_DESIGNABLEe IBInspectable, tuttavia, poiché queste vengono create come attributi di runtime definiti dall'utente.


Beh, era solo un'idea. Ho rimosso CustomView.m dalla destinazione e ho ricevuto avvisi simili durante l'esecuzione dell'app.
Martin R

Sembra un vero gremlin dato il tuo confronto con una macchina apparentemente identica (che differisce in qualche modo). Hai provato a postare su devforum? Sembra che tu stia volando alla cieca senza ulteriori informazioni e il tuo processo sembra ragionato e razionale. L'avvertimento "build" potrebbe non significare troppo in quanto Xcode è pieno di messaggi di errore fuorvianti. Per i calci però, hai provato Editor -> "debug visualizzazione selezionata", giusto? (Probabilmente non funzionerà, ma merita un controllo di sanità mentale). Inoltre, viene visualizzato qualcosa nell'app Console (di registrazione)?
Chris Conover

Sto avendo lo stesso problema. Mines con un singolo file xib contenente un IB_DESIGNABLE. Tuttavia, controllando la mia configurazione, ho già attivato l'aggiornamento automatico e ora ho provato gli aggiornamenti manuali, cancellando prima i dati derivati, ecc. Finora nulla ha funzionato. La cosa strana è che avevo questo controllo che funzionava bene, poi si è fermato. E non credo di aver cambiato codice intermedio. Pazzo.
drekka

Mostrava avvisi come sopra. Ora ho creato una seconda classe con il codice copiato dall'originale IB progettabile. Questa classe funziona perfettamente e quando sono tornata alla classe non operaia originale, ora funziona bene. Da questo ho concluso che c'è qualche cache da qualche parte (non nei dati derivati) che non viene cancellata fino a quando il designable ib originale non viene scambiato con un altro designable ib. Il passaggio a una UIView non sembra svuotare questa cache. Solo un altro ib progettabile. Vai a capire :-)
drekka

Risposte:


75

Sulla base del suggerimento di Chrisco di eseguire il debug della vista selezionata (cosa che avevo già fatto, ma sono andato a riprovare per buona misura), ho notato un paio di altre opzioni nella parte inferiore del menu Editor.

  • Aggiorna automaticamente le viste
  • Aggiorna tutte le viste

Ho fatto clic su "Aggiorna tutte le visualizzazioni" e dopo che Xcode ci ha pensato un po ', improvvisamente lo storyboard mostrava la mia vista come previsto (applicando correttamente le mie IBInspectableproprietà).

inserisci qui la descrizione dell'immagine

Ho quindi ripetuto l'intero processo per confermare che questa è la soluzione.

Ho creato una nuova classe, ThirdView. Questa classe è identica alle altre, ancora una volta. Ho cambiato la classe della mia vista in ThirdViewe questa volta ho ottenuto qualcosa di leggermente diverso:

inserisci qui la descrizione dell'immagine

Facendo clic su "Mostra" agli avvisi:

inserisci qui la descrizione dell'immagine

Questa volta uno nuovo:

Utilizzo della classe UIView per oggetto con classe personalizzata perché la classe ThirdView non esiste.

Questo non è davvero più utile di quello che già esisteva. Inoltre, ora gli altri tre avvertimenti sono raddoppiati in 6 stranamente.

Ad ogni modo, se faccio di nuovo clic su "Aggiorna tutte le viste" dal menu a discesa dell'Editor, tutti gli errori scompaiono e, ancora una volta, la vista viene visualizzata correttamente.

Tuttavia, fino a questo punto, tutto ciò che ho fatto è stato roba con cui non ho mai scherzato a casa. A casa, ha funzionato e basta. Quindi ho attivato "Aggiorna automaticamente le visualizzazioni" e ho creato una "FourthView" da testare, ancora una volta, identica alle prime tre.

Dopo aver cambiato la classe della vista in "FourthView", l'etichetta designabile ha detto "Aggiornamento" per un breve momento, quindi alla fine ha detto "Aggiornato":

inserisci qui la descrizione dell'immagine

Quindi, ho controllato il mio computer a casa. "Aggiorna automaticamente le viste" è attivato sul computer che ha sempre funzionato. Era spento al computer che non lo era. Non ricordo di aver mai toccato questa opzione di menu. Non posso nemmeno dirti con certezza se esistesse prima di Xcode 6. Ma questa opzione è ciò che stava facendo la differenza.


TL; DR, se stai riscontrando lo stesso problema descritto nella domanda, assicurati che "Aggiorna automaticamente le viste" sia attivato (o manualmente "Aggiorna tutte le viste" quando hai bisogno di un aggiornamento in IB):

inserisci qui la descrizione dell'immagine


2
In realtà stavo cercando come spegnerlo poiché continua a eseguire il rendering in background rendendo i vecchi MacBook molto lenti. Grazie!
Departamento B

Questo potrebbe risolversi temporaneamente, ma controlla la risposta di @ Martin-Gilles Lavoie
Ashley Mills

22

Ho qualche dettaglio in più che potrebbe causare il mancato caricamento delle classi IBDesignable.

Seleziona il tuo storyboard / xib problematico in cui dovrebbero essere visualizzate le visualizzazioni personalizzate.

Nell'area del navigatore, vai al Navigatore rapporti nell'area di lavoro / progetto XCode.

Nel menu Editor di XCode, premi (come menzionato da nhgrif), l'opzione "Aggiorna tutte le viste". Ciò farà sì che IB lancerà una compilazione per un sacco di cose che, sono certo, non ti aspetteresti.

Nel Navigatore report, fare clic su "Per gruppo" per filtrare il contenuto e osservare la sezione "Interface Builder". Vedrai che per caricare il framework delle visualizzazioni IBDesignable personalizzato, compilerà MOLTE cose. Se uno qualsiasi di questi obiettivi NON viene compilato, come (forse deprecati) obiettivi di unit test (anche se sono totalmente estranei al codice che carica queste visualizzazioni o storyboard), IB non riuscirà a caricare la dll.

Nel mio caso, IB ha cercato di compilare 8 obiettivi, inclusi 4 quelli in cui i test unitari non erano stati aggiornati dalle recenti modifiche di refactoring su cui abbiamo lavorato.

La maggior parte delle modifiche / correzioni al codice che ho fatto per consentire a IB di caricare e visualizzare correttamente le mie visualizzazioni personalizzate dove non sono correlate o addirittura collegate a queste classi, né caricherà mai lo storyboard durante l'esecuzione di questi test unitari. Tuttavia, IB dipendeva dall'intero spazio di lavoro che lo compilava perché funzionasse.


Ehi, quindi come faccio a impedire a IB di provare a caricare e visualizzare visualizzazioni non correlate o collegate a queste classi?
HannahCarney

Presumo che abbia a che fare con le dipendenze dell'intestazione. Sia che le classi progettabili stiano toccando altre classi, nel momento in cui viene visualizzato l'header creerà quelle implementazioni correlate. Apple sta giocando con il codice del grafico delle dipendenze sorgente in XC7GM che fallisce completamente nel nostro progetto con XCode che si blocca durante la creazione del grafico. I seguenti 7.1beta non mostrano il problema. Il nostro sistema di compilazione automatizzato per il momento dipende ancora dalla versione 6.4, quindi non abbiamo esaminato come risolverlo ulteriormente in XC6.4. Salteremo direttamente a 7.1GM.
Martin-Gilles Lavoie

Se hai più target / progetti, questa è assolutamente la risposta giusta e risolve davvero il problema - TUTTI i target devono essere costruiti in modo pulito, non sapevo nemmeno che ci fosse una sezione "Interface Builder" nel navigatore di report! Tutte le altre risposte che ho visto sono fondamentalmente molti gesti che potrebbero risolverlo temporaneamente, ma questa è la soluzione definitiva. Molto bene.
Ashley Mills,

3
Quindi, in base a questo, possiamo concludere che l'attributo IB_DESIGNABLE è una merda totale e una perdita di tempo. Basta evitare di usarlo.
m8labs

IB_DESIGNABLE non ha nulla a che fare con il problema e la soluzione sopra elencati. È semplicemente un flag NO-OP per IB per individuare cose utilizzabili. Hai solo bisogno di mantenere una casa pulita.
Martin-Gilles Lavoie

22

Solo un rapido suggerimento per chiunque abbia questo problema: ricordati di specificare il tipo di variabile.

// Doesn't show up in IB
@IBInspectable var includeLeftSection = true

// Shows now that it knows the type
@IBInspectable var includeLeftSection : Bool = true

6

Ho avuto lo stesso avvertimento Ignoring user defined runtime attribute for key path .. anche se sono assolutamente sicuro di non aver fatto nulla di sbagliato con la mia classe di visualizzazione IBDesignable personalizzata.

Si è scoperto, nel mio caso, che aveva a che fare con la cache di Xcode.

rm -rf ~/Library/Developer/Xcode/DerivedData/*

Elimina DerivedDatae l'avvertimento è sparito.


1
Scorciatoia in XCode per ottenere lo stesso risultato: ⌘⇧K
Mojo66

@ Mojo66 Credo che Clean Build sia diverso dall'eliminazione della cartella DerivedData. Ovviamente, a volte una build pulita è abbastanza buona per risolvere alcuni problemi di cache di Xcode.
samwize

@ Mojo66 probabilmente intendevi ⌘⌥⇧K (cmd + alt + shift + K)
tzaloga

5

Nel caso in cui qualcun altro si imbatta nell'errore, la classe IB Designables non esiste, per lo stesso motivo per cui ho fatto io. La risposta principale non era il mio problema ... ma ecco un problema leggermente correlato ...

C'è una proprietà nascosta nel codice sorgente dello storyboard chiamata customModule.

Ad esempio, avevo una classe chiamata ForwardArrow all'interno di un framework separato che ho accidentalmente aggiunto al mio obiettivo principale.

Quindi l'XML per alcune visualizzazioni è finito come customClass = "ForwardArrow" customModule = "MainTargetNameWasHere"

Quando li ho rimossi dal target principale nella build, lo story board non ha aggiornato MainTargetNameWasHere a CustomViews che è il framework in cui si trovava e ha iniziato a dare che nessuna classe ha trovato errori.

Quindi TLDR; Assicurati che se il tuo IBDesignable si trova in un altro framework che l'attributo xml customModule nello storyboard sia impostato sul valore corretto. E se non c'è affatto aggiungilo.

Esempio dalla mia fonte:

<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="MUG-jc-2Ml" customClass="ForwardArrow" customModule="CustomViews">

1
Santo cielo, questo mi ha fatto impazzire per un giorno. Che brutto insetto.
GoldenJoe

5

Come esempio, stavo usando CheckboxButton tramite pod e la grafica della casella di controllo non viene mai visualizzata nello storyboard mentre ho ricevuto gli stessi problemi descritti nella domanda qui:

avviso: IB Designables: utilizzo della classe UIView per oggetto con classe personalizzata perché la classe CheckboxButton non esiste

e

avvertenza: IB Designables: ignorare l'attributo di runtime definito dall'utente per il percorso chiave "checkColor" sull'istanza di "UIView". Hit un'eccezione quando si tenta di impostare il suo valore: [setValue: forUndefinedKey:]: questa classe non è conforme alla codifica del valore della chiave per la chiave checkColor.

Il modo in cui ha risolto il mio problema è stato quello di fornire al modulo il nome CheckboxButton come di seguito:

Nota: dovresti sostituire CheckboxButton con qualunque sia il nome del modulo che stai usando.


4

Ho risolto personalmente questo problema utilizzando il pulsante "-" per eliminare il contenuto dal mio ispettore di identità. Quando rimuovi le classi personalizzate, modifichi il contenuto nell'IB e quindi aggiungi una nuova classe personalizzata, gli elementi progettabili nell'Ispettore di identità non vengono rimossi e mi ha causato quell'errore. Basta eliminare tutto e ricostruire.inserisci qui la descrizione dell'immagine


Ho fatto esattamente quello che hai detto e ha risolto il mio problema. Tutte le soluzioni precedenti qui esposte non ce l'hanno fatta. Molte grazie. ; o)
XLE_22

@ XLE_22 a volte sono le risposte che nessuno guarda a risolverlo, eh? :)
HannahCarney

Ho avuto un problema in cui ho rinominato una proprietà IBInspectable su alcuni dei miei xib. Dopo averlo fatto, ho ricevuto un sacco di avvisi che mi informavano che XCode non riusciva a trovare la proprietà ora rinominata. La rimozione della proprietà dall'ispettore di identità ha risolto il mio problema.
WBuck

1

So che c'è una risposta, ma ecco un'altra esperienza.

Stavo riscontrando alcuni problemi non correlati a questo problema, ma nel processo ho rimosso @IBInspectable dai vars nella mia classe e ho eliminato gli attributi dall'Identity Inspector (alt-apple-3).

Dopo aver risolto il problema (codice) con il componente, ho aggiornato tutto un sacco di volte, ma ancora nessun attributo nell'ispettore di identità.

Alla fine, ho notato che erano tornati, ma solo nell'ispettore degli attributi (alt-apple-4) . Non appena ho aggiunto loro dei valori lì, sono riapparsi nell'ispettore di identità


1

La risposta di Dave Thomas sopra mi ha dato la soluzione (inversa) quando non gli altri (Dati derivati, Editor> Aggiorna) l'hanno fatto, ma per motivi di chiarezza nel caso in cui le persone non siano sicure di dove modificare l'XML ... non ne ho bisogno!

  1. Nel tuo file storyboard seleziona la vista fastidiosa
  2. Nella barra laterale di destra seleziona la scheda Ispettore identità (terza opzione da sinistra).
  3. Avrai la tua classe personalizzata, che dovrebbe essere già impostata, e il file Module. Per me questo era vuoto e stavo ottenendo gli stessi errori di OP. Ho impostato il nome delModule mio progetto e BAM: ha iniziato a funzionare dopo la ricostruzione!

0

Ho appena esaminato la suoneria su questo problema. Ho provato tutte le cose elencate qui e altrove senza fortuna. Questo è uno storyboard che ha funzionato bene per sempre e improvvisamente ha smesso di funzionare con il problema "Ignorare l'attributo di runtime definito dall'utente ...".

Per qualsiasi motivo, rimuovendo questo codice da uno dei miei IBDesignable è stato risolto:

-(void)viewDidLoad {
    self.clipsToBounds = YES;
}

la rimozione di questo causava la scomparsa di tutti gli avvisi, anche in altri oggetti IBDesignable. Non ho idea del motivo per cui questo passaggio lo abbia risolto, ma forse aiuterà anche qualcun altro.


3
Ti manca la chiamata a cena qui
RolandasR

0

Avevo lo stesso problema e ho dovuto cambiare cornerRadius e BorderWidth in una stringa e poi lanciarlo su CGFloat, era l'unica soluzione per me per poter modificare i valori e vedere le modifiche nel generatore di interfacce.

@IBInspectable var borderColor: UIColor? {
    didSet {
        layer.borderColor = borderColor!.CGColor
    }
}

@IBInspectable var borderWidth: String? {
    didSet {
        layer.borderWidth = CGFloat(Int(borderWidth!) ?? 0)
    }
}

@IBInspectable var cornerRadius: String? {
    didSet {
        layer.cornerRadius = CGFloat(Int(cornerRadius!) ?? 0)
        layer.masksToBounds = layer.cornerRadius > 0
    }
}

Penso che IBInspectable possa fare solo alcuni tipi, quindi forse avresti dovuto usarlo al Floatposto di CGFloate lanciarlo invece
Fonix
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.