IB_DESIGNABLE, IBInspectable: el constructor de interfaces no se actualiza

91

Tengo el siguiente conjunto de código:

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

(Para referencia de Swift, este problema también ocurría con el código 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
        }
    }
}

Agregué UIViewa un controlador de vista en el guión gráfico y establecí su subclase en CustomView.

ingrese la descripción de la imagen aquí

Esto agrega la fila "Designables". Está atascado en "Actualizando" y la información sobre herramientas dice "Esperando que Target se compile". Nunca cambia de este estado.

Cuando me muevo a la inspección de atributos, puedo establecer estas IBInspectablepropiedades:

ingrese la descripción de la imagen aquí

Y una vez configurados, también aparecen en los "Atributos de tiempo de ejecución definidos por el usuario":

ingrese la descripción de la imagen aquí

Sin embargo, el estado de "Designables" nunca se mueve más allá de "Actualizando" con la misma información sobre herramientas (he intentado compilar Cmd + B varias veces, nada cambia).

Además, a medida que configuro las IBInspectablepropiedades, recibo una advertencia para cada una:

IBDesignables - Ignorando el atributo de tiempo de ejecución definido por el usuario para la ruta de acceso clave "borderColor" en la instancia de "UIView" ... esta clase no es compatible con la codificación de valores clave para el key borderColor.

Captura de pantalla de las advertencias generadas:

ingrese la descripción de la imagen aquí


Estoy familiarizado con los problemas que cumplen con la codificación de valores clave y, en general, sé cómo resolverlos ... pero no entiendo cómo resolver este problema aquí. Según el inspector de identidad de la vista, la vista es una "Vista personalizada" (no una "UIView" normal, que no tiene estas propiedades). Y si la vista no fuera una "Vista personalizada", estas propiedades designables no aparecerían en el Inspector de atributos, ¿verdad? Pero cuando Interface Builder intenta aplicar estos atributos a la vista, vuelve a pensar que la clase de la vista es "UIView" y no puede aplicar los atributos.

¿Alguna ayuda? Por favor, avíseme si he omitido algún detalle importante, pero por lo que vale, seguí este tutorial exactamente (aparte de ObjC vs Swift). También vale la pena señalar que seguí este tutorial exactamente en otra máquina y funcionó como un encanto (tenía la intención de hacer esta publicación anoche, pero la computadora en la que estaba entonces no tenía este problema).


Según los comentarios, se ha sugerido que quizás el .marchivo no esté incluido y eso podría estar causando el problema. Pensé que seguramente habría salido de mi camino para que este escenario fuera el caso, pero lo comprobé de todos modos.

ingrese la descripción de la imagen aquí

Cuando comencé a intentar hacer esto, entendía que las IB_DESIGNABLEclases tenían que ser parte de un UIKitmarco diferente . Así que desde esta primera pantalla, se puede ver que he creado un marco "CustomViews", que tiene una clase, CustomView. También verá aquí que también creé un OtherView, que es idéntico a CustomView, excepto que no está en un marco separado. Sin embargo, el problema idéntico persiste en el guión gráfico entre ambas clases.

Aquí tenemos una captura de pantalla indicando que CustomView.mse incluye para ser construido con el CustomViewsframework:

ingrese la descripción de la imagen aquí

Mientras tanto, la siguiente captura de pantalla indica varias cosas:

  • CustomViews.framework se incluye adecuadamente en el proyecto principal.
  • OtherView.mtambién se incluye como fuente de compilación, por lo que incluso si algo está mal CustomView, OtherViewdebería funcionar, sin embargo, genera errores idénticos.
  • Main.storyboardy LaunchScreen.xibse muestran en rojo. No tengo idea de por qué, y no tengo la menor idea de por qué LaunchScreen.xibdebería (no he tocado este archivo), aunque puedo decir que después de mirar otros proyectos, Main.storyboardtambién aparece en rojo para esos proyectos, y estoy no hacer nada con IB_DESIGNABLEo IBInspectableallí.

ingrese la descripción de la imagen aquí


He intentado y vuelto a intentar esto varias veces. Funciona siempre en mi computadora en casa; no puedo reproducir el problema descrito en esta pregunta en casa. En el trabajo, nunca funciona. El problema descrito en esta pregunta ocurre todo el tiempo.

Ambas computadoras son Mac Minis compradas nuevas este año (no los nuevos modelos, modelo de finales de 2012). Ambas computadoras ejecutan OS X Yosemite 10.10. Ambos equipos ejecutan Xcode versión 6.1. En casa, la construcción es (6A1052d). Esta mañana, puedo confirmar que ambas computadoras están ejecutando versiones idénticas de Xcode.

Otros me han sugerido que podría ser una mala RAM. Eso me parece inverosímil. Reinicié el proyecto varias veces, reinicié la computadora varias veces. Me parece que si hubiera una mala RAM en una computadora de aproximadamente 6 meses de antigüedad, estaría viendo otros problemas y que este problema sería menos constante. Pero este problema persiste a pesar de que muchas veces se reinicia todo el proyecto desde cero y se reinicia por completo en la computadora.


Vale la pena señalar que si realmente compilo y ejecuto este proyecto, la vista personalizada con las IBInspectablepropiedades realmente se muestra como espero que lo muestre el guión gráfico. Sin embargo, imagino que este sería el caso incluso sin las directivas IB_DESIGNABLEy IBInspectable, ya que se crean como atributos de tiempo de ejecución definidos por el usuario.

nhgrif
fuente
Bueno, fue solo una idea. Eliminé CustomView.m del objetivo y luego recibí advertencias similares al ejecutar la aplicación.
Martin R
Eso parece un verdadero gremlin dada su comparación con una máquina aparentemente idéntica (que de alguna manera difiere). ¿Ha intentado publicar en devforums? Parece que está volando a ciegas sin información adicional, y su proceso parece razonado y racional. La advertencia de "compilación" puede no significar demasiado ya que Xcode está plagado de mensajes de error engañosos. Sin embargo, para divertirse, ha probado Editor -> "depurar vista seleccionada", ¿verdad? (Probablemente no funcione, pero vale la pena comprobarlo). Además, ¿aparece algo en la aplicación de consola (de registro)?
Chris Conover
Estoy teniendo el mismo problema. Minas con un solo archivo xib que contiene un IB_DESIGNABLE. Sin embargo, comprobando mi configuración, ya tengo activada la actualización automática y ahora he probado las actualizaciones manuales, borrando primero los datos derivados, etc. Hasta ahora nada, nada ha funcionado. Lo extraño es que tenía este control funcionando bien, luego se detuvo. Y no creo que haya cambiado ningún código intermedio. Loco.
drekka
Estaba mostrando advertencias como se indica arriba. Ahora he creado una segunda clase con el código copiado del IB designable original. Esta clase funciona perfectamente y cuando cambié de nuevo a la clase no trabajadora original, ahora funciona bien. A partir de esto, he llegado a la conclusión de que hay algo de caché en algún lugar (no en los datos derivados) que no se borra hasta que el ib designable original se intercambia por otro ib designable. Cambiar a un UIView no parece borrar este caché. Sólo otro ib designable. Ir a figura :-)
drekka

Respuestas:

75

Basado en la sugerencia de chrisco de depurar la vista seleccionada (que ya había hecho, pero fui a intentarlo de nuevo por si acaso), noté un par de otras opciones en la parte inferior del menú Editor.

  • Actualizar vistas automáticamente
  • Actualizar todas las vistas

Hice clic en "Actualizar todas las vistas" y después de que Xcode pensara un poco, de repente el guión gráfico mostraba mi vista como se esperaba (aplicando correctamente mis IBInspectablepropiedades).

ingrese la descripción de la imagen aquí

Luego pasé por todo el proceso nuevamente para confirmar que esta es la solución.

He creado una nueva clase, ThirdView. Esta clase es idéntica a las demás, nuevamente. Cambié la clase de mi vista a ThirdViewy obtuve algo ligeramente diferente esta vez:

ingrese la descripción de la imagen aquí

Haciendo clic en "Mostrar" para ver las advertencias:

ingrese la descripción de la imagen aquí

Uno nuevo esta vez:

Usando la clase UIView para el objeto con clase personalizada porque la clase ThirdView no existe.

En realidad, esto no es más útil que lo que ya existía. Además, ahora las otras tres advertencias se han duplicado en 6 extrañamente.

De todos modos, si hago clic en "Actualizar todas las vistas" del menú desplegable del Editor nuevamente, todos los errores desaparecen y, una vez más, la vista se muestra correctamente.

Aún así, hasta este punto, todo lo que hice fueron cosas con las que nunca me metí en casa. En casa, simplemente funcionó. Así que encendí "Actualizar vistas automáticamente" y creé una "FourthView" para probar, una vez más, idéntica a las tres primeras.

Después de cambiar la clase de la vista a "FourthView", la etiqueta de designables decía "Actualizando" por un breve momento y finalmente decía "Up to date":

ingrese la descripción de la imagen aquí

Entonces, revisé mi computadora en casa. La opción "Actualizar vistas automáticamente" está activada en la computadora que siempre estaba funcionando. Estaba apagado en la computadora que no lo estaba. No recuerdo haber tocado esta opción de menú. Ni siquiera puedo decirles con certeza si existía antes de Xcode 6. Pero esta opción es lo que marca la diferencia.


TL; DR, si tiene el mismo problema descrito en la pregunta, asegúrese de que "Actualizar vistas automáticamente" esté activado (o "Actualizar todas las vistas" manualmente cuando necesite una actualización en IB):

ingrese la descripción de la imagen aquí

nhgrif
fuente
2
De hecho, estaba buscando cómo apagarlo, ya que sigue renderizándose en segundo plano, lo que hace que las MacBooks más antiguas sean realmente lentas. ¡Gracias!
Departamento B
Esto puede resolverse temporalmente, pero consulte la respuesta de @ Martin-Gilles Lavoie
Ashley Mills
22

Tengo algunos detalles más que pueden hacer que sus clases IBDesignable no se carguen.

Seleccione su storyboard / xib problemático donde deberían mostrarse sus vistas personalizadas.

En el área del navegador, diríjase al Navegador de informes en su espacio de trabajo / proyecto XCode.

En el menú Editor de XCode, presione (como lo menciona nhgrif), la opción "Actualizar todas las vistas". Esto hará que IB lance una compilación para un montón de cosas que, estoy seguro, no esperarías.

En el Navegador de informes, haga clic en "Por grupo" para filtrar el contenido y consulte la sección "Creador de interfaces". Verá que, por el bien de cargar el marco de vistas IBDesignable personalizado, compilará MUCHAS cosas. Si alguno de estos objetivos NO se compila, como los objetivos de prueba unitaria (quizás en desuso) (incluso si no están relacionados en absoluto con el código que carga estas vistas o el guión gráfico), IB fallará al cargar su dll.

En mi caso, IB trató de compilar 8 objetivos, incluidos 4 que eran pruebas unitarias que no se habían actualizado desde los cambios de refactorización recientes en los que hemos estado trabajando.

La mayoría de los cambios / correcciones de código que he realizado para que IB cargue y muestre correctamente mis vistas personalizadas donde no están relacionadas o incluso vinculadas con estas clases, ni nunca cargaría el guión gráfico en el curso de la ejecución de estas pruebas unitarias. Sin embargo, IB dependía de la compilación del espacio de trabajo completo para que funcionara.

Martin-Gilles Lavoie
fuente
Oye, ¿cómo evito que IB intente cargar y mostrar vistas no relacionadas o vinculadas a estas clases?
HannahCarney
Supongo que tiene que ver con las dependencias del encabezado. Ya sea que las clases designables estén tocando otras clases, en el momento en que se vea el encabezado, se generarán esas implementaciones relacionadas. Apple está jugando con el código del gráfico de dependencia de origen en XC7GM que falla por completo en nuestro proyecto y XCode falla cuando está construyendo el gráfico. Los siguientes 7.1betas no presentan el problema. Nuestro sistema de compilación automatizado todavía depende de 6.4 por el momento, por lo que no hemos investigado cómo resolver esto más en XC6.4. Saltaremos directamente a 7.1GM.
Martin-Gilles Lavoie
Si tiene varios objetivos / proyectos, esta es absolutamente la respuesta correcta y realmente soluciona el problema: TODOS los objetivos deben compilarse limpiamente, ¡ni siquiera sabía que había una sección de "Creador de interfaces" en el navegador de informes! Todas las otras respuestas que he visto son básicamente un montón de movimientos de la mano que podrían arreglarlo temporalmente, pero esta es la solución definitiva. Bien hecho.
Ashley Mills
3
Entonces, de acuerdo con esto, podemos concluir que el atributo IB_DESIGNABLE es una mierda total y una pérdida de tiempo. Simplemente evite usarlo.
m8labs
IB_DESIGNABLE no tiene nada que ver con el problema y la solución enumerados anteriormente. Es simplemente una bandera NO-OP para que IB detecte cosas utilizables. Solo necesitas mantener una casa limpia.
Martin-Gilles Lavoie
22

Solo una pista rápida para cualquier otra persona que tenga este problema: recuerde especificar el tipo de variable.

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

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

Recibí la misma advertencia Ignoring user defined runtime attribute for key path ..aunque estoy absolutamente seguro de que no hice nada malo con mi clase de vista IBDesignable personalizada.

Resultó que, en mi caso, tenía que ver con el caché de Xcode.

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

Purga DerivedDatay la advertencia desaparece.

samwize
fuente
1
Atajo en XCode para lograr el mismo resultado: ⌘⇧K
Mojo66
@ Mojo66 Creo que Clean Build es diferente de purgar la carpeta DerivedData. Por supuesto, en algún momento una compilación limpia es lo suficientemente buena para resolver ciertos problemas de almacenamiento en caché de Xcode.
samwize
@ Mojo66 probablemente quisiste decir ⌘⌥⇧K (cmd + alt + shift + K)
tzaloga
5

En caso de que alguien más se encuentre con el error La clase IB Designables no existe, por la misma razón que yo. La respuesta principal no fue mi problema ... pero aquí hay un problema ligeramente relacionado ...

Hay una propiedad oculta en el código fuente del storyboard llamada customModule.

Por ejemplo, tenía una clase llamada ForwardArrow dentro de un marco separado que agregué accidentalmente a mi objetivo principal.

Entonces, el XML de algunas vistas terminó como customClass = "ForwardArrow" customModule = "MainTargetNameWasHere"

Cuando los eliminé del objetivo principal en la compilación, el guión gráfico no actualizó MainTargetNameWasHere a CustomViews, que es el marco donde estaba ubicado y comenzó a dar que no se encontró ningún error de clase.

Entonces TLDR; Asegúrese de que si su IBDesignable está en otro marco, el atributo xml customModule en su storyboard esté configurado en el valor correcto. Y si no está allí, agréguelo.

Ejemplo de mi fuente:

<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="MUG-jc-2Ml" customClass="ForwardArrow" customModule="CustomViews">
Dave Thomas
fuente
1
Mierda, esto me ha estado volviendo loco por un día. Qué pequeño insecto tan desagradable.
GoldenJoe
5

Como mi ejemplo, estaba usando CheckboxButton a través de pod y los gráficos de la casilla de verificación nunca aparecen en el guión gráfico mientras tengo los mismos problemas descritos en la pregunta aquí:

advertencia: IB Designables: usando la clase UIView para un objeto con clase personalizada porque la clase CheckboxButton no existe

y

advertencia: IB Designables: ignorando el atributo de tiempo de ejecución definido por el usuario para la ruta de clave "checkColor" en la instancia de "UIView". Haga una excepción al intentar establecer su valor: [setValue: forUndefinedKey:]: esta clase no es compatible con la codificación del valor clave para la clave checkColor.

La forma en que resolví mi problema fue proporcionar el módulo con el nombre CheckboxButton de la siguiente manera:

Nota: debe reemplazar CheckboxButton por el nombre del módulo que esté utilizando.

Incluso Cheng
fuente
4

Personalmente resolví este problema usando el botón "-" para eliminar contenido de mi inspector de identidad. Cuando elimina clases personalizadas, cambia el contenido en el IB y luego agrega una nueva clase personalizada, los elementos designables en el inspector de identidad no se eliminan y eso me provocó ese error. Simplemente elimine todo y reconstruya.ingrese la descripción de la imagen aquí

HannahCarney
fuente
Hice exactamente lo que dijiste y resolvió mi problema. Todas las soluciones anteriores expuestas aquí no lo lograron. Muchas gracias. ; o)
XLE_22
@ XLE_22 a veces son las respuestas que nadie mira las que lo resuelven, ¿eh? :)
HannahCarney
Tuve un problema en el que cambié el nombre de una propiedad IBInspectable en algunos de mis xib. Después de hacer eso, tuve un montón de advertencias que me informaban que XCode no podía encontrar la propiedad ahora renombrada. Quitar la propiedad del inspector de identidad solucionó mi problema.
WBuck
1

Sé que esto está respondido, pero aquí hay una experiencia más.

Estaba teniendo algunos problemas no relacionados con este problema, pero en el proceso eliminé @IBInspectable de las variables de mi clase y eliminé los atributos del inspector de identidad (alt-apple-3).

Después de solucionar el problema (de código) con el componente, actualicé todo un montón de veces, pero todavía no hay atributos en el inspector de identidad.

Finalmente, noté que estaban de regreso, pero solo en el inspector de atributos (alt-apple-4) . Tan pronto como les agregué valores allí, reaparecieron en el inspector de identidad.

Gordon Dove
fuente
1

La respuesta de Dave Thomas anterior me dio la solución (inversa) cuando no lo hicieron los demás (Datos derivados, Editor> Actualizar), pero en aras de la claridad en caso de que la gente no esté segura de dónde editar el XML ... ¡No es necesario!

  1. En su archivo de guión gráfico, seleccione la vista problemática
  2. En la barra lateral derecha, seleccione la pestaña Inspector de identidad (tercera opción desde la izquierda).
  3. Tendrá su clase personalizada, que ya debería estar configurada, y el Module. Para mí, esto estaba vacío y recibía los mismos errores que OP. Configuré el nombre deModule mi proyecto y BAM: ¡comenzó a funcionar después de la reconstrucción!
por qué código por qué
fuente
0

Acabo de pasar por el timbre de este problema. Probé todas las cosas enumeradas aquí y en otros lugares sin suerte. Este es un guión gráfico que funcionó bien para siempre y de repente dejó de funcionar con el problema "Ignorando el atributo de tiempo de ejecución definido por el usuario ...".

Por alguna razón, eliminar este código de uno de mis IBDesignable lo solucionó:

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

la eliminación de esto hizo que todas las advertencias desaparecieran, incluso en otros objetos IBDesignable. No tengo idea de por qué este paso lo solucionó, pero tal vez también ayude a alguien más.

IMFletcher
fuente
3
te falta llamar a cenar aquí
RolandasR
0

Estaba teniendo el mismo problema y tuve que cambiar cornerRadius y BorderWidth para que fueran String y luego convertirlo en CGFloat, era la única solución para mí poder cambiar los valores y ver los cambios en el generador de interfaces.

@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
    }
}
Chuy47
fuente
Creo que IBInspectable solo puede hacer ciertos tipos, por lo que tal vez habría necesitado usar en Floatlugar de CGFloaty lanzar eso en su lugar
Fonix