@IBDesignable ошибка: IB Designables: не удалось обновить статус автоматического макета: Интерфейсный конструктор Cocoa Touch Tool потерпел крах

157

У меня есть очень простой подкласс UITextView, который добавляет функциональность «Заполнитель», которую можно найти встроенной в объект «Текстовое поле». Вот мой код для подкласса:

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

После изменения класса для UITextViewобъекта в Инспекторе Identity PlaceholderTextView, я могу просто установить Placeholderсвойство в Инспекторе Атрибутов. Код прекрасно работает при запуске приложения, но не отображает текст заполнителя в конструкторе интерфейса. Я также получаю следующие неблокирующие ошибки (я полагаю, именно поэтому он не отображается во время разработки):

ошибка: IB Designables: не удалось обновить состояние автоматического макета: Интерфейсный конструктор Cocoa Touch Tool потерпел крах

ошибка: IB Designables: не удалось отобразить экземпляр PlaceholderTextView: визуализация представления заняла более 200 мс. Ваш код рисования может страдать от низкой производительности.

Я не могу понять, что является причиной этих ошибок. Вторая ошибка не имеет никакого смысла, так как я даже не переопределяю drawRect (). Любые идеи?

Альберт Бори
источник
1
Я получаю эту ошибку. Объект работал нормально в тестовом проекте, но не в моем основном проекте (в таблице). Согласно developer.apple.com/library/mac/recipes/… , я выбрал «Выбрать редактор»> «Отладка выбранных представлений». Затем я получил «Не удалось отладить представления» «Убедитесь, что ваш фреймворк имеет правильные параметры сборки для сборки для iOS». В Google ничего не появилось по этой ошибке.
Мэтт

Ответы:

238

При сбое Интерфейсного Разработчика Cocoa Touch Tool создаются отчеты о сбоях. Тезисы расположены ~/Library/Logs/DiagnosticReportsи названы IBDesignablesAgentCocoaTouch_*.crash. В моем случае они содержали полезную трассировку стека, которая идентифицировала проблему в моем коде.

Petter
источник
1
Спасибо! Это было очень полезно! Где вы нашли информацию о сообщениях о сбоях? :)
Ben-G
57
В моем случае я обнаружил, что initFrame(frame: CGRect)должен быть определен. Сделайте это, если вы предоставите свой собственный initметод (ы).
Трэвис
Это было лучшее решение. Я не был реализацией initWithFrame в одном из представлений.
HotFudgeSunday
3
Я использовал диагностические отчеты и, как упомянуто @Travis, мне нужно было init(frame: CGRect)явно переопределить, потому что у меня был собственный iniметод. Возможно, вы захотите просмотреть отчет о use of unimplemented initializer 'init(frame:)'сбое непосредственно Application Specific Informationв отчете. Спасибо, парни! Двойной выигрыш в этом ответе!
Крис
4
Как обычно, этот файл журнала также доступен в приложении Mac OS Console в группе отчетов о диагностике пользователей .
Пауло Маттос
51

У меня была такая же проблема пару раз. Оба раза это начиналось, когда я загружал перо IBDesignable на раскадровку, когда перо не могло поместиться на виде (то есть у меня была кнопка с UIView, но все еще в кончике). Как только я исправил этот Xcode, он по-прежнему выдавал мне ошибки, поэтому я перезапускал Xcode, пока он случайно не перестал выдавать мне ошибку.

Надеюсь, это поможет.

ОБНОВЛЕНИЕ: я только что убил все процессы, названные «Интерфейсный Разработчик Какао Touch Tool», перезапустил XCode, и ошибка исчезла. Не знаю, будет ли это всегда работать или нет.

Дастин Уильямс
источник
2
Хотя я до сих пор не понимаю, почему, если вы не перезаписали ни один из initметодов, код, размещенный как часть вопроса, больше не отображает IB Designablesошибки, и заполнитель правильно отображается в Интерфейсном Разработчике.
Уиллингтон Вега
2
Возможно, это ошибка, и нам просто нужно дождаться ее исправления. Возможно в Xcode 6.3.
Юсеф Моавад
3
XCode 7.1.1 и до сих пор присутствует. Перезапуск XCode не решил проблему. Мне пришлось вручную убить все процессы, называемые Interface Builder Cocoa Touch Tool, затем XCode потерпел крах, перезапустил его и он начал работать.
Кристиан Пена
1
Важный момент: действительно, сначала убейте процессы конструктора интерфейса, затем остановите XCode - если вы сделаете это, проблема не исчезнет ...
TheEye
2
XCode 8.1 эта ошибка все еще происходит. Первоначально вызвано отсутствием переопределения init, но сохраняется после добавления init. Пришлось убивать процессы Interface Builder, как описано, ТОГДА перезапустить xcode, как говорит @TheEye,
Джон Фаулер,
39

В моем случае я делал следующее в методах initWithFrame / initWithCoder для создания представления:

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

Похоже, я не должен был использовать Main Bundle , а вместо этого связку класса. Поэтому я заменил этот код на следующий, и он работал:

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

Я подумал, что это может кому-нибудь помочь.

jmoukel
источник
1
Это исправило мою проблему тоже! Спасибо @jmoukel!
edopelawi
Это исправило мою проблему. Мужчина!!! я не мог заметить эту строку "bundleForClass", хотя я смотрел на это решение пару раз. :(
elk_cloner
let bundle = Bundle(for: ValidatingTextField.self)в Свифт
ср
14

Вы можете выбрать свой собственный вид в Interface Builder , а затем использовать Editor, Debug Selected Views. Он запустит так называемый IBDesignableAgentCocoaTouchсеанс отладки, когда все точки останова (включая точки прерывания исключений) сработают, и вы сможете точно определить место, где происходит сбой вашего представления.

Федор Волчек
источник
Отлично! Это также нашло мою проблему - неправильный шрифт. Что объясняет, почему только один из шести очень похожих IBDesignables терпел неудачу.
zkarj
13

Для Xcode 8 - Swift

Добавление необязательного значения в качестве значения по умолчанию при @IBInspectableвозникновении проблемы для меня.

Это не сработает:

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

Это должно работать:

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

class func getDefaultImage() -> UIImage {
    if let defaultImage = UIImage(named: "myImage") {
        return defaultImage
    } else {
        return UIImage()
    }
}
Мухаммед Заид Патан
источник
@DungTran С какой проблемой вы сталкиваетесь?
Мухаммед Заид Патан
1
Дополнительная обработка предотвращает сбой. Но знаете ли вы, что заставляет UIImage (named :) возвращать ноль последовательно?
ScottyBlades
Комментирование этого кода исправило его для меня `@objc @available (*, устарело, переименовано:" backgroundColor ") @IBInspectable public var signatureBackgroundColor: UIColor = .white {didSet {backgroundColor = signatureBackgroundColor}}`
PhoneyDeveloper
9

Я сталкивался с подобными проблемами в Интерфейсном Разработчике, отрисовывающих дизайн.

Используя технику, предложенную в этом ответе, я смог отследить проблему до использования литералов изображений.

Сбой рендеринга

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

Нет сбоя рендеринга

self.backgroundImage.image =  UIImage(named: "rectangleCenter")
Ник Кросс
источник
Вы герой.
Натангиттер
Есть идеи, почему литералы изображений несовместимы с IB? Я была такая же проблема.
SwiftsNamesake
6

На самом деле, если у вас есть какие-то старые определенные пользователем атрибуты (которые не действительны для текущего представления) в любом представлении вашей раскадровки, это может привести к сбою вашего агента.

Кроме того, иногда это происходит только из-за неприятной ошибки Xcode. Чтобы это проверить, снимите флажок «Редактор»> «Автоматически обновлять представления», затем перейдите в другой файл, очистите и перезапустите проект. После того, как вы снова вошли в раскадровку, вы можете нажать «Редактор»> «Обновить представления» и снова проверить автоматический режим. Это тоже однажды решило мою проблему.

Если оба не сработали, то, вероятно, вы сделали что-то не так с вашим представлением IBDesignable, поэтому выберите сбойные представления в раскадровке и отладьте их, нажав «Редактор»> «Представления отладки».

Юсуф Камиль А.К.
источник
Вы подарок от Бога.
andrewcar
4

Это не относится к этому вопросу, но, возможно, я помогу кому-то еще.

У меня была похожая проблема, когда в моем классе @IBDesignable я не реализовал оба:

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

    // custom setup
}

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

    // custom setup
}
tzaloga
источник
Вы всегда должны реализовывать оба метода init. Init с фреймом используется, когда вы инициализируете представление из кода, а init с aDecoder используется из InterfaceBuilder.
Skodik.o
4

У меня была та же проблема, и я решил ее, добавив 'use_frameworks!' в подфиле моего проекта.

Надеюсь, это поможет вам.

Джимми Нг
источник
Это сработало для меня, когда у меня возникла эта проблема с JVFloatLabeledTextField
saswanb
Это было то, что сработало для меня, приняв старый проект Obj-C, который был довольно устаревшим. ИБ загорается как рождественская елка после этого! Спасибо.
..
3

В моем случае это было как-то связано с каркасным каркасом, который я использовал. Мне пришлось добавить $ (PROJECT_DIR) / Carthage / Build / iOS в настройку сборки Runpath Search Paths

AkademiksQc
источник
Попробовав все остальные опубликованные решения ... это было единственное исправление, которое сработало для меня! Спасибо!
Джоэл
3

В моем случае это была проблема с OneSignal. Видимо, у них есть ошибка в версии 2.2.0 и выше. Перешел на 2.1.6 и все снова отлично!

Проверьте это .

Пол Разван Берг
источник
1

Когда я отладил это, я обнаружил, что есть некоторые классы, которые модифицируют интерфейс. Обычно это маркированная метка, которая является подклассом UILabel или любого другого подкласса класса UIView и рисует пользовательский интерфейс во время выполнения и сталкивается с движком Autolayout. Попробуйте задать фиксированную ширину или высоту для этих пользовательских видов. Если это не решит вашу проблему, попробуйте следующие решения: -

Решение 1: - Раскомментируйте #use_frameworks внутри вашего файла pod.

Решение 2: - Попробуйте удалить производные данные. 1. Закройте окно редактора вашего XCode и выйдите из симулятора -> 2. Перейдите в «Настройки XCode» -> «Местоположения» -> 3. Нажмите маленькую серую стрелку, показывающую путь к производным данным -> 4. Выберите ваш проект -> 5. Удалите все папки внутри -> 6. Выйдите из Xcode и снова откройте

Ашиш Писей
источник
1

Добавьте его в конец вашего Podfile и запустите 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
Тисса
источник
1

Добавьте этот скрипт в конец моего Podfileи pod installснова выполните .

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
Гарольдо Гондим
источник
1

Основная проблема заключается в том, что при создании @ IBDesignable убедитесь, что файл cocoapod не включен в UITests, иначе это вызовет этот сбой.

Модесто Кабрера
источник
0

Я нахожу причину в том, что ваш xib не такого размера, как дизайн в раскадровке. Убедитесь, что xib имеет одинаковую высоту и ширину.

user6476366
источник
0

Я просто пропустил эту строку кода, platform :ios, '7.0' и проблема была решена. Только эта строка в вашем файле pod и обновление вашего pod проблема будет решена.

Шахзаиб Макбул
источник
0

Для меня это был отсутствующий сертификат подписи, потому что я никогда не запускал приложение, поэтому Xcode еще не создавал сертификат. Как только я запустил приложение, IBDesignableрендеринг работал нормально.

Флориан Пфистерер
источник
0

Это как если бы вы получили код от другого разработчика и получили эту ошибку. Просто беги

pod install

Это сработало для меня. Надеюсь, поможет.

Дхрув Хатри
источник
0

Убедитесь, что вы не инициализируете напрямую UIImageили не UIFontиспользуете ресурсы или шрифты, добавленные в ваш проект.

Я всегда создаю private func setUp()в моих @IBDesignableпользовательских UIклассах. который вызывается из init(frame: CGRect), init?(coder aDecoder: NSCoder). Поэтому я, наконец, обновил setup()следующее.

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
}
Совик Долуй
источник
-1

Просто позвольте ему создавать и запускать на симуляторе, если у вас есть ошибка где-то еще в проекте, просто закомментируйте его и сначала запустите designable, чтобы обновить designable и раскомментировать другие коды. Меня устраивает.

Даниил
источник