Erreur @IBDesignable: IB Designables: Échec de la mise à jour de l'état de la mise en page automatique: Interface Builder Cocoa Touch Tool s'est écrasé

157

J'ai une sous-classe très simple de UITextView qui ajoute la fonctionnalité "Placeholder" que vous pouvez trouver native à l'objet Text Field. Voici mon code pour la sous-classe:

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

Après avoir changé la classe de l' UITextViewobjet dans l'inspecteur d'identité sur PlaceholderTextView, je peux définir la Placeholderpropriété très bien dans l'inspecteur d'attributs. Le code fonctionne très bien lors de l'exécution de l'application, mais n'affiche pas le texte d'espace réservé dans le générateur d'interface. J'obtiens également les erreurs non bloquantes suivantes (je suppose que c'est pourquoi il n'est pas rendu au moment de la conception):

erreur: IB Designables: échec de la mise à jour de l'état de la mise en page automatique: Interface Builder Cocoa Touch Tool a planté

erreur: IB Designables: échec du rendu de l'instance de PlaceholderTextView: le rendu de la vue a pris plus de 200 ms. Votre code de dessin peut souffrir de performances lentes.

Je ne suis pas en mesure de comprendre la cause de ces erreurs. La deuxième erreur n'a aucun sens, car je ne remplace même pas drawRect (). Des idées?

Albert Bori
la source
1
J'obtenais cette erreur. L'objet a bien fonctionné dans un projet de test, mais pas dans mon projet principal (dans un tableau). Selon developer.apple.com/library/mac/recipes/… , j'ai choisi Choisir l'éditeur> Déboguer les vues sélectionnées. Ensuite, j'ai obtenu "Impossible de déboguer les vues" "Assurez-vous que votre framework dispose des paramètres de construction appropriés pour la construction pour iOS." Rien n'est venu dans Google pour cette erreur.
Matt

Réponses:

238

Des rapports d'erreur sont générés lorsque l'Interface Builder Cocoa Touch Tool plante. Les thèses sont localisées ~/Library/Logs/DiagnosticReportset nommées IBDesignablesAgentCocoaTouch_*.crash. Dans mon cas, ils contenaient une trace de pile utile qui identifiait le problème dans mon code.

Petter
la source
1
Merci! C'était super utile! Où avez-vous trouvé les informations sur les rapports de plantage? :)
Ben-G
57
Dans mon cas, j'ai découvert qu'il initFrame(frame: CGRect)fallait définir cela. Faites-le si vous fournissez vos propres initméthodes.
Travis
C'était la meilleure solution. Je n'ai pas implémenté initWithFrame sur l'une des vues.
HotFudgeSunday
3
J'ai utilisé les rapports de diagnostic et comme @Travis l'a mentionné, je devais remplacer init(frame: CGRect)explicitement le parce que j'avais une iniméthode personnalisée . Vous voudrez peut-être consulter le rapport d' use of unimplemented initializer 'init(frame:)'incident directement sous Application Specific Informationle rapport. Merci les gars! Double victoire dans cette réponse!
Chris
4
Comme d'habitude, ce fichier journal est également disponible dans l' application macOS Console , sous le groupe Rapports de diagnostic utilisateur .
Paulo Mattos
51

J'ai eu le même problème à plusieurs reprises. Les deux fois, cela a commencé lorsque je chargeais une pointe IBDesignable sur le storyboard lorsque la pointe ne pouvait pas s'adapter à la vue (c'est-à-dire que j'avais un bouton hors de l'UIView mais toujours dans la pointe). Une fois que j'ai corrigé que Xcode me donnait toujours des erreurs, j'ai redémarré Xcode jusqu'à ce qu'il cesse de me donner l'erreur.

J'espère que ça aide.

MISE À JOUR: Je viens de tuer tous les processus nommés "Interface Builder Cocoa Touch Tool", redémarré Xcode et l'erreur a disparu. Je ne sais pas si cela fonctionnera toujours ou non.

Dustin Williams
la source
2
Bien que je ne comprends toujours pas pourquoi, si vous n'écrasez aucune des initméthodes, le code publié dans le cadre de la question ne montre plus les IB Designableserreurs et l'espace réservé est correctement rendu dans Interface Builder.
Willington Vega
2
C'est peut-être un bogue et nous devons juste attendre qu'il soit corrigé. Peut-être dans Xcode 6.3.
Youssef Moawad
3
XCode 7.1.1 et toujours présent. Le redémarrage de XCode n'a pas résolu le problème. J'ai dû tuer manuellement tous les processus appelés Interface Builder Cocoa Touch Tool, puis XCode s'est écrasé, l'a redémarré et il a commencé à fonctionner.
Cristian Pena du
1
Point important: En effet, Tuez D'ABORD les processus de
création d'
2
XCode 8.1 cette erreur se produit toujours. Initialement causé par l'absence de remplacement d'initialisation mais persistant après l'ajout d'init. Dû tuer les processus Interface Builder comme décrit PUIS redémarrer xcode comme le dit @TheEye
John Fowler
39

Dans mon cas, je faisais le suivant dans les méthodes initWithFrame / initWithCoder pour créer la vue:

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

Il semble que je n'étais pas censé utiliser le bundle principal , mais plutôt le bundle de la classe. J'ai donc remplacé ce code pour ce qui suit et cela a fonctionné:

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

J'ai pensé que cela pourrait peut-être aider quelqu'un.

Jmoukel
la source
1
Cela a aussi résolu mon problème! Merci @jmoukel!
edopelawi
Celui-là a résolu mon problème. Homme!!! Je n'ai pas remarqué cette ligne "bundleForClass" même si j'ai examiné cette solution deux fois. :(
elk_cloner
let bundle = Bundle(for: ValidatingTextField.self)à Swift
Cfr
14

Vous pouvez sélectionner votre vue personnalisée dans Interface Builder et puis utilisez Editor, Debug Selected Views. Il lancera une soi-disant IBDesignableAgentCocoaTouchsession de débogage lorsque tous les points d'arrêt (y compris les points d'arrêt d'exception) fonctionnent et que vous pourrez identifier exactement l'endroit où votre vue se bloque.

Fyodor Volchyok
la source
Parfait! Cela a également trouvé mon problème - une police incorrecte. Ce qui explique pourquoi un seul des six IBDesignables très similaires a échoué.
zkarj
13

Pour Xcode 8 - Swift

Ajout d'une valeur facultative comme valeur par défaut lors de la @IBInspectablecréation du problème pour moi.

Cela ne fonctionnera pas:

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

Cela devrait fonctionner:

@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
la source
@DungTran À quel problème êtes-vous confronté?
Mohammad Zaid Pathan
1
La gestion facultative empêche le crash. Mais savez-vous ce qui fait que UIImage (named :) renvoie nil de manière cohérente?
ScottyBlades
Commenter ce code l'a corrigé pour moi `@objc @available (*, obsolète, renommé:" backgroundColor ") @IBInspectable public var signatureBackgroundColor: UIColor = .white {didSet {backgroundColor = signatureBackgroundColor}}`
PhoneyDeveloper
9

J'étais confronté à des problèmes similaires d'Interface Builder pour rendre les designables.

En utilisant la technique suggérée dans cette réponse, j'ai pu retracer le problème jusqu'à l'utilisation des littéraux d'image.

Crash de rendu

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

Aucun crash de rendu

self.backgroundImage.image =  UIImage(named: "rectangleCenter")
Nick Cross
la source
Vous êtes un héros.
nathangitter
Une idée de pourquoi les littéraux d'image sont incompatibles avec IB? J'ai eu le même problème.
SwiftsNamesake
6

En fait, si vous avez d' anciens attributs définis par l'utilisateur (qui ne sont pas valides pour la vue actuelle) dans n'importe quelle vue de votre storyboard, cela peut provoquer le blocage de votre agent.

De plus, cela arrive parfois juste à cause d'un vilain bogue de Xcode. Pour le vérifier, lorsque vous êtes au storyboard, décochez Editeur> Actualiser automatiquement les vues, puis passez à un autre fichier, nettoyez et redémarrez votre projet. Une fois que vous avez à nouveau entré le storyboard, vous pouvez cliquer sur Editeur> Actualiser les vues et cocher à nouveau une vue automatique. Celui-ci a également résolu mon problème une fois.

Si les deux ne fonctionnent pas, alors vous avez probablement fait quelque chose de mal à propos de votre vue IBDesignable, alors choisissez vos vues plantées dans le storyboard et le débogage en cliquant sur Éditeur> Vues de débogage

Yusuf Kamil AK
la source
Vous êtes un don de Dieu.
andrewcar
4

Ce n'est pas le cas pour cette question, mais je vais peut-être aider quelqu'un d'autre.

J'ai eu un problème similaire lorsque dans ma classe @IBDesignable je n'ai pas implémenté les deux:

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

    // custom setup
}

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

    // custom setup
}
tzaloga
la source
Vous devez toujours implémenter les deux méthodes init. Init with frame est utilisé lorsque vous initiez votre vue à partir du code et init with aDecoder est utilisé à partir d'InterfaceBuilder.
Skodik.o
4

J'ai eu le même problème et je l'ai résolu en ajoutant le 'use_frameworks!' au Podfile de mon projet.

J'espère que cela vous aide.

Jimmy Ng
la source
Cela a fonctionné pour moi quand j'ai eu ce problème avec JVFloatLabeledTextField
saswanb
C'est ce qui a fonctionné pour moi, en adoptant un projet Obj-C plus ancien qui était assez dépassé. L'IB s'illumine comme un sapin de Noël après ça! Je vous remercie.
nul ..
3

Dans mon cas, c'était en quelque sorte lié à un cadre de carthage que j'utilisais. J'ai dû ajouter $ (PROJECT_DIR) / Carthage / Build / iOS au paramètre de construction Runpath Search Paths

AkademiksQc
la source
Après avoir essayé toutes les autres solutions publiées ... c'était la seule solution qui a fonctionné pour moi! Merci!
Joel
3

Dans mon cas, c'était un problème avec OneSignal. Apparemment, ils ont un bogue dans la version 2.2.0 et supérieure. Passé à 2.1.6 et tout est à nouveau super!

Regardez ceci .

Paul Razvan Berg
la source
1

Lorsque j'ai débogué cela, j'ai découvert qu'il existe des classes qui modifient l'interface utilisateur. Typiquement marquelabel qui est une sous-classe d'UILabel ou de toute autre classe sous-classant UIView et dessinant l'interface utilisateur au moment de l'exécution et entrant en collision avec le moteur Autolayout. Essayez de donner une largeur ou une hauteur fixe pour ces vues personnalisées. Si cela ne résout pas votre problème, essayez les solutions suivantes: -

Solution 1: - Décommentez #use_frameworks dans votre fichier pod.

Solution 2: - Essayez de supprimer les données dérivées. 1. Fermez la fenêtre de l'éditeur de votre Xcode et quittez le simulateur -> 2. Allez dans Préférences Xcode -> Emplacements -> 3. Cliquez sur la petite flèche grise montrant le chemin des données dérivées -> 4. Sélectionnez votre projet -> 5. Supprimez tous les dossiers à l'intérieur -> 6. Quittez Xcode et rouvrez

Ashish Pisey
la source
1

Ajoutez-le au bas de votre Podfile et exécutez 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
la source
1

Ajoutez ce script à la fin de mon Podfileet pod installrecommencez.

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
la source
1

Un problème majeur est lorsque vous créez @ IBDesignable, assurez-vous que le fichier cocoapod n'est pas inclus dans les UITests, sinon cela provoquera ce plantage.

Modesto Cabrera
la source
0

Je trouve que la raison en est que votre xib n'est pas de la même taille que le design du storyboard. Assurez-vous que le xib a la même hauteur et la même largeur.

user6476366
la source
0

Il me manquait juste cette ligne de code platform :ios, '7.0' et le problème a été résolu. Juste cette ligne dans votre fichier pod et mettre à jour votre problème de pod sera résolu.

Shahzaib Maqbool
la source
0

Pour moi, c'était un certificat de signature manquant, car je n'ai jamais exécuté l'application, donc Xcode n'a pas encore créé de certificat. Une fois que j'ai exécuté l'application, le IBDesignablerendu a bien fonctionné.

Florian Pfisterer
la source
0

C'est comme si vous aviez du code d'un autre développeur et que vous obteniez cette erreur. Courez

pod install

Cela a fonctionné pour moi. J'espère que ça aide.

Dhruv Khatri
la source
0

Assurez-vous que vous n'initialisez pas directement UIImageouUIFont n'utilisez pas les actifs ou les polices ajoutés dans votre projet.

Je crée toujours un private func setUp()dans mes classes @IBDesignablepersonnalisées UI. qui est appelé à partir init(frame: CGRect), init?(coder aDecoder: NSCoder). J'ai donc finalement mis à jour le setup()comme suit.

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
la source
-1

Laissez-le simplement construire et fonctionner sur le simulateur si vous avez une erreur ailleurs dans le projet, commentez-le et exécutez d'abord Designable pour mettre à jour Designable et décommenter les autres codes. Ça marche pour moi.

Daniel
la source