@IB Error de designación: Designables de IB: no se pudo actualizar el estado del diseño automático: la herramienta táctil del generador de interfaz se bloqueó

157

Tengo una subclase muy simple de UITextView que agrega la funcionalidad "Marcador de posición" que puede encontrar nativa del objeto Campo de texto. Aquí está mi código para la subclase:

import UIKit
import Foundation

@IBDesignable class PlaceholderTextView: UITextView, UITextViewDelegate
{
    @IBInspectable var placeholder: String = "" {
        didSet {
            setPlaceholderText()
        }
    }
    private let placeholderColor: UIColor = UIColor.lightGrayColor()        
    private var textColorCache: UIColor!
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.delegate = self
    }
    
    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.delegate = self
    }
    
    func textViewDidBeginEditing(textView: UITextView) {
        if textView.text == placeholder {
            textView.text = ""
            textView.textColor = textColorCache
        }
    }
    
    func textViewDidEndEditing(textView: UITextView) {
        if textView.text == "" && placeholder != "" {
            setPlaceholderText()
        }
    }
    
    func setPlaceholderText() {
        if placeholder != "" {
            if textColorCache == nil { textColorCache = self.textColor }
            self.textColor = placeholderColor
            self.text = placeholder
        }
    }
}

Después de cambiar la clase para el UITextViewobjeto en el Inspector de identidad a PlaceholderTextView, puedo establecer la Placeholderpropiedad muy bien en el Inspector de atributos. El código funciona muy bien cuando se ejecuta la aplicación, pero no muestra el texto del marcador de posición en el generador de interfaces. También recibo los siguientes errores sin bloqueo (supongo que es por eso que no se está procesando en tiempo de diseño):

error: Designables de IB: no se pudo actualizar el estado del diseño automático: la herramienta táctil del creador de interfaces de Cocoa se bloqueó

error: Designables de IB: no se pudo procesar la instancia de PlaceholderTextView: la representación de la vista tardó más de 200 ms. Su código de dibujo puede sufrir un rendimiento lento.

No puedo entender qué está causando estos errores. El segundo error no tiene ningún sentido, ya que ni siquiera estoy anulando drawRect (). ¿Algunas ideas?

Albert Bori
fuente
1
Estaba recibiendo este error. El objeto funcionó bien en un proyecto de prueba, pero no en mi proyecto principal (en una tabla). De acuerdo con developer.apple.com/library/mac/recipes/… , elegí Elegir editor> Depurar vistas seleccionadas. Luego recibí "No se pudieron depurar las vistas" "Asegúrese de que su marco tenga la configuración de compilación correcta para compilar para iOS". No surgió nada en Google para este error.
Matt

Respuestas:

238

Se generan informes de fallas cuando se bloquea la herramienta táctil Interface Builder Cocoa. Las tesis están ubicadas ~/Library/Logs/DiagnosticReportsy nombradas IBDesignablesAgentCocoaTouch_*.crash. En mi caso, contenían un útil seguimiento de pila que identificaba el problema en mi código.

Petter
fuente
1
¡Gracias! ¡Esto fue súper útil! ¿Dónde encontraste la información sobre los informes de fallos? :)
Ben-G
57
En mi caso, descubrí que initFrame(frame: CGRect)debe definirse. Hágalo si proporciona sus propios initmétodos.
Travis
Esta fue la mejor solución. No estaba implementando initWithFrame en una de las vistas.
HotFudgeSunday
3
Usé los informes de diagnóstico y, como mencionó @Travis, necesitaba anularlos init(frame: CGRect)explícitamente porque tenía un inimétodo personalizado . Es posible que desee consultar el informe de bloqueo use of unimplemented initializer 'init(frame:)'directamente debajo Application Specific Informationdel informe. ¡Gracias chicos! ¡Doble victoria en esta respuesta!
Chris
44
Como es habitual, este archivo de registro también está disponible en la aplicación Console macOS, en el grupo Informes de diagnóstico del usuario .
Paulo Mattos
51

He tenido el mismo problema un par de veces. Ambas veces comenzó cuando estaba cargando una plumilla IBDesignable en el guión gráfico cuando la plumilla no cabía en la vista (es decir, tenía un botón fuera de la UIView pero todavía en la plumilla). Una vez que arreglé que Xcode todavía me daba errores, reinicié Xcode hasta que dejó de darme el error al azar.

Espero que esto ayude.

ACTUALIZACIÓN: Acabo de matar todos los procesos llamados "Interface Builder Cocoa Touch Tool", reinicié Xcode y el error desapareció. No sé si esto siempre funcionará o no.

Dustin Williams
fuente
2
Aunque todavía no entiendo por qué, si no sobrescribe ninguno de los initmétodos, el código publicado como parte de la pregunta ya no muestra los IB Designableserrores y el marcador de posición se representa correctamente en el Creador de interfaces.
Willington Vega
2
Quizás esto sea un error y solo tenemos que esperar a que se solucione. Quizás en Xcode 6.3.
Youssef Moawad
3
XCode 7.1.1 y todavía presente. Reiniciar XCode no resolvió el problema. Tuve que matar manualmente todos los procesos llamados Interface Builder Cocoa Touch Tool, luego XCode se bloqueó, lo reinicié y comenzó a funcionar.
Cristian Pena
1
Punto importante: De hecho, PRIMERO elimine los procesos del generador de interfaces, luego detenga XCode; si lo hace al revés, el problema persiste ...
TheEye
2
XCode 8.1 este error todavía ocurre. Originalmente causado por no tener anulación de inicio pero persistió después de que se agregó init Tuve que matar los procesos de Interface Builder como se describe LUEGO reiniciar xcode como dice @TheEye
John Fowler
39

En mi caso, estaba haciendo lo siguiente en los métodos initWithFrame / initWithCoder para crear la vista:

className = NSStringFromClass([self class]);
self.view = [[[NSBundle mainBundle] loadNibNamed:className owner:self options:nil] firstObject];

Parece que no debía usar el paquete principal , sino el paquete de la clase. Así que reemplacé ese código por lo siguiente y funcionó:

bundle = [NSBundle bundleForClass:[self class]];
className = NSStringFromClass([self class]);
self.view = [[bundle loadNibNamed:className owner:self options:nil] firstObject];

Pensé que tal vez esto podría ayudar a alguien.

jmoukel
fuente
1
¡Esto solucionó mi problema también! Gracias @jmoukel!
edopelawi
Ese solucionó mi problema. ¡¡¡Hombre!!! No pude notar esa línea "bundleForClass" a pesar de que busqué esta solución un par de veces. :(
elk_cloner
let bundle = Bundle(for: ValidatingTextField.self)en Swift
Cfr
14

Usted puede seleccionar la vista personalizada en el Interface Builder y el uso a continuación Editor, Debug Selected Views. IBDesignableAgentCocoaTouchLanzará la llamada sesión de depuración cuando todos los puntos de interrupción (incluidos los puntos de interrupción de excepción) funcionen y usted pueda identificar exactamente el lugar donde se bloquea su vista.

Fyodor Volchyok
fuente
¡Perfecto! Esto también encontró mi problema: una fuente incorrecta. Lo que explica por qué solo uno de los seis IBDesignables muy similares estaba fallando.
zkarj
13

Para Xcode 8 - Swift

Agregar valor opcional como valor predeterminado al @IBInspectablecausarme un problema.

Esto no funcionará:

@IBInspectable var repeatImage: UIImage = UIImage(named:"myImage")!{
      didSet {
       // configureView
      }
}

Esto debería funcionar:

@IBInspectable var repeatImage: UIImage = RepeatImageView.getDefaultImage() {
    didSet {
        // configureView()
    }
}

class func getDefaultImage() -> UIImage {
    if let defaultImage = UIImage(named: "myImage") {
        return defaultImage
    } else {
        return UIImage()
    }
}
Mohammad Zaid Pathan
fuente
@DungTran ¿Qué problema estás enfrentando?
Mohammad Zaid Pathan
1
El manejo opcional evita el choque. Pero, ¿sabes qué está causando que UIImage (named :) regrese nil constantemente?
ScottyBlades
Al comentar este código, lo arregló para mí `@objc @available (*, desaprobado, renombrado:" backgroundColor ") @IBInspectable public var signatureBackgroundColor: UIColor = .white {didSet {backgroundColor = signatureBackgroundColor}}`
PhoneyDeveloper
9

Estaba experimentando los problemas similares de Interface Builder al representar los designables.

Utilizando la técnica sugerida en esta respuesta pude rastrear el problema hasta el uso de literales de imagen.

Renderizado

self.backgroundImage.image =  #imageLiteral(resourceName: "rectangleCenter")

Sin bloqueo de renderizado

self.backgroundImage.image =  UIImage(named: "rectangleCenter")
Nick Cross
fuente
Usted es un héroe.
nathangitter
¿Alguna idea de por qué los literales de imagen son incompatibles con IB? Tuve el mismo problema.
SwiftsNamesake el
6

En realidad, si tiene algunos atributos definidos por el usuario antiguos (que no son válidos para la vista actual) en cualquier vista de su guión gráfico, eso puede hacer que su agente se bloquee.

Además, a veces sucede solo por un error desagradable de Xcode. Para verificarlo, cuando esté en el guión gráfico desmarque Editor> Actualizar automáticamente las vistas, luego muévase a otro archivo, limpie y reinicie su proyecto. Después de ingresar nuevamente al guión gráfico, puede hacer clic en Editor> Actualizar vistas y verificar automáticamente uno nuevamente. Ese también resolvió mi problema una vez.

Si ambos no funcionaron, entonces probablemente haya hecho algo mal con respecto a su vista IBDesignable, así que elija sus vistas bloqueadas en el guión gráfico y depúrelas haciendo clic en Editor> Vistas de depuración

Yusuf Kamil AK
fuente
Eres un regalo de Dios.
andrewcar
4

Este no es el caso para esta pregunta, pero tal vez pueda ayudar a alguien más.

Tuve un problema similar cuando en mi clase @IBDesignable no implementé ambos:

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

    // custom setup
}

override init(frame: CGRect) {
    super.init(frame: frame)

    // custom setup
}
tzaloga
fuente
Siempre debe implementar ambos métodos init. Init con frame se usa cuando inicia su vista desde el código e init con aDecoder se usa desde InterfaceBuilder.
Skodik.o
4

Tuve el mismo problema y lo resolví agregando 'use_frameworks!' al Podfile de mi proyecto.

Espero que te ayude.

Jimmy Ng
fuente
Esto funcionó para mí cuando tuve este problema con JVFloatLa LabelTextField
saswanb
Esto fue lo que funcionó para mí, adoptar un proyecto antiguo de Obj-C que estaba bastante desactualizado. ¡El IB se ilumina como un árbol de Navidad después de esto! Gracias.
sorteo ..
3

En mi caso, de alguna manera estaba relacionado con un marco de cartago que estaba usando. Tuve que agregar $ (PROJECT_DIR) / Carthage / Build / iOS a la configuración de compilación Runpath Search Paths

AkademiksQc
fuente
Después de probar todas las otras soluciones publicadas ... ¡esta fue la única solución que funcionó para mí! ¡Gracias!
Joel
3

En mi caso, fue un problema con OneSignal. Aparentemente, tienen un error dentro de la versión 2.2.0 y superior. ¡Cambió a 2.1.6 y todo vuelve a estar bien!

Mira esto .

Paul Razvan Berg
fuente
1

Cuando depuré esto descubrí que hay algunas clases que están modificando la interfaz de usuario. Por lo general, marquelabel, que es una subclase de UILabel o cualquier otra clase que subclasifique UIView y dibuje ui en tiempo de ejecución y colisione con el motor Autolayout. Intente dar ancho o alto fijo para estas vistas personalizadas. Si no resuelve su problema, intente las siguientes soluciones: -

Solución 1: - Descomente #use_frameworks dentro de su archivo pod.

Solución 2: intente eliminar los datos derivados. 1. Cierre la ventana del editor de su Xcode y salga del simulador -> 2. Vaya a Preferencias de Xcode -> Ubicaciones -> 3. Haga clic en la pequeña flecha gris que muestra la ruta de datos derivados -> 4. Seleccione su proyecto -> 5. Elimine todas las carpetas dentro -> 6. Salga de Xcode y vuelva a abrir

Ashish Pisey
fuente
1

Añádelo al final de tu Podfile y ejecuta pod install

# Workaround for Cocoapods issue #7606

    post_install do |installer|
        installer.pods_project.build_configurations.each do |config|
            config.build_settings.delete('CODE_SIGNING_ALLOWED')
            config.build_settings.delete('CODE_SIGNING_REQUIRED')
        end
    end
Tissa
fuente
1

Agregue este script al final de mi Podfiley realice pod installnuevamente.

post_install do |installer|
    installer.pods_project.build_configurations.each do |config|
        config.build_settings.delete('CODE_SIGNING_ALLOWED')
        config.build_settings.delete('CODE_SIGNING_REQUIRED')
    end
end
Haroldo Gondim
fuente
1

Un problema importante es cuando crea @ IBDesignable, asegúrese de que el archivo cocoapod no esté incluido en los UITests o de lo contrario causará este bloqueo.

Modesto Cabrera
fuente
0

Creo que la razón es que su xib no tiene el mismo tamaño que el diseño en el guión gráfico. Asegúrese de que el xib tenga la misma altura y anchura.

usuario6476366
fuente
0

Solo me faltaba esta línea de código platform :ios, '7.0' y el problema se resolvió. Solo esta línea en su archivo pod y actualizará su problema pod se resolverá.

Shahzaib Maqbool
fuente
0

Para mí era un certificado de firma faltante, porque nunca ejecuté la aplicación, por lo que Xcode aún no creó un certificado. Una vez que ejecuté la aplicación, el IBDesignablerenderizado funcionó bien.

Florian Pfisterer
fuente
0

Es como si obtuviera Código de otro Desarrollador y obtiene este error. Solo corre

pod install

Esto funcionó para mí. Espero eso ayude.

Dhruv Khatri
fuente
0

Asegúrese de que no está inicializando directamente UIImageo UIFontutilizando activos o fuentes agregadas en su proyecto.

Siempre creo un private func setUp()en mis clases @IBDesignablepersonalizadas UI. que se llama a partir de init(frame: CGRect), init?(coder aDecoder: NSCoder). Así que finalmente actualicé setup()el siguiente.

private func setUp() {

     //... Doing initial configurations

     // iconImageView.image = UIImage(named: "IconImageName")! // Causing the Crash, use if let OR guard let instead
     if let icon = UIImage(named: "IconImageName") {
          iconImageView.image = icon
          iconImageView.frame.size = icon.size
     }

     // nameLabel.font =  UIFont(name: "Calibri-Light", size: 15.0) // Causing the Crash, use if let OR guard let instead
     if let font = UIFont(name: "Calibri-Light", size: size) {
          nameLabel.font =  font
     } else {
          nameLabel.font = UIFont.systemFont(ofSize: size) 
     }

     // Doing other stuffs
}
Sauvik Dolui
fuente
-1

Simplemente deje que se construya y ejecute en el simulador si tiene un error en otro lugar del proyecto, simplemente coméntelo y ejecute el primero para actualizarlo y descomentar los otros códigos. Esto funciona para mi.

Daniel
fuente